LINUX.ORG.RU

Зачем нужны GC, Java, .NET?


0

0

Имеем для каждого объекта счетчик ссылок на него. Исчезает последняя ссылка --> объект удаляется. Запрещаем при этом ручную работу с указателями. Получаем то же самое, что и в Java или .NET, но без огромного оверхеда. Те же Genie или Vala работают по такому принципу, хотя там и есть возможность рулить памятью руками (но чисто опционально). При этом они не таскают за собой большую дуру под названием JVM и работают куда быстрее.

Так в чем прикол «безопасного программирования» по Сану или Микрософту в таком случае?

Ответ на: комментарий от LamerOk

А если надо счтывать строки файла только после символов «<plain>»? Как тут помогут языки со своими короткими файловыми конструкциями и сборщиками мусора?

anonymous
()
Ответ на: комментарий от LamerOk

Или тут уже меряние языками заканчивается и начинаются суровые будни прикладных библиотек?

anonymous
()
Ответ на: комментарий от anonymous

> А если надо счтывать

А если не надо? А если надо, но не то? Завязывай с пустой болтовней не по теме.

LamerOk ★★★★★
()
Ответ на: комментарий от LamerOk

И что тут плохого есть? Никаких указателей нет, сборщиков мусора нет. Всё само закрется и удалится.

{
  ifstream f("name");
  string s;
  while (getline(f, s))
  {
    /////
  }
}

anonymous
()
Ответ на: комментарий от svr69

> Всякие JIT-ы и так должны делать вызовы пустых функций практически нулевыми.
Но это значит, что если мы потеряли список из миллиона объектов без финализации, сборщик мусора не может отвезти их на полигон и выбросить гнить под солнцем и дождём, а обязан перебрать каждый объект из этого миллиона и вызвать для него пустой финализатор. Я соврешенно не уверен, что это так уж дёшево.

den73 ★★★★★
()
Ответ на: комментарий от Legioner

Вот мой вариант для Дельфи:

var stackFrame:variant; 
begin
stackFrame:=mkStackFrame;
// при выходе из области видимости переменной
// stackFrame созданный здесь объект "страж кадра стека" удалится. 
o:=TObject.Create; onStack(o); 
// деструктор для o будет вызван при разрушении stackFrame
...

end; 

Итак, мы размениваем вложенность на лишние вызовы. С моей точки зрения, это упрощает код. И ещё я сделал для Дельфи слабые указатели. Хотя ими могут ссылаться друг на друга только наследники TComponent.

den73 ★★★★★
()
Ответ на: комментарий от Legioner

чем в D? Каким местом, для этого конкретного случая(работа с файлом)(особенно «менее гибко»)?

using из C# кстати довольно таки убого, это да - то же самое убогое RAII, вид сбоку. В лиспе же мы имеем механизм unwind-protect и макросы, соответственно - можем определить что-нибудь вроде

(defmacro with-cleaners ((&rest resources) &body body)
  "Each resource form is of form (name value &rest initial-cleaner-forms)"
  (let ((cleaners (gensym)))
    `(let (,@(loop for (name value) in resources
                   collect `(,name ,value)))
       (let ((,cleaners
               (list (lambda ()
                       ,@(reduce #'nconc
                                 (mapcar #'cddr resources))))))
         (macrolet ((add-cleaner (&rest cleaner-body)
                      `(progn
                         (push (lambda () ,@cleaner-body)
                               ,',cleaners)
                         nil)))
           (labels ((invoke-cleaners ()
                      (if (null ,cleaners)
                        nil
                        (let ((cleaner (pop ,cleaners)))
                          (unwind-protect
                            (funcall cleaner)
                            (invoke-cleaners))))))
             (unwind-protect
               (progn ,@body)
               (invoke-cleaners))))))))
Cleanup формы в этом макросе можно как обозначать наверху, так и добавлять по ходу дела. Вызываться они будут в порядке стека от наиболее новых к старым, вплоть до тех, что заданы изначально. Если в каком-то из них произойдет ошибка, выполнение других форм, дальше по стеку, прервано не будет, т.к. они завернуты в unwind-protect, как видно. Можно также вызывать cleanup формы заранее, в таком случае они все аннулируются, т.е. в конце области видимости уже не вызовутся. Пример, вобщем:
(defun do-something ()
  (format t "~&Doing some work...~%"))

(with-cleaners ((f (open "~file.tmp" :direction :output
                         :if-exists :supersede)
                   (close f)
                   (delete-file f))) ;;file stream может обозначать путь к файлу
  (do-something)
  (write-line "Hello, world!" f)
  (do-something)
  (add-cleaner (close f)
               (with-open-file (in f :direction :input)
                 (write-line "File contents:")
                 (loop for s = (read-line in nil nil)
                       while s
                       do (write-line s)))
               (setf f (open f :direction :output
                             :if-exists :append)))
  (do-something))

Love5an
()

> Имеем для каждого объекта счетчик ссылок на него. Исчезает последняя ссылка --> объект удаляется. Запрещаем при этом ручную работу с указателями.

Так и сделано в Perl. Переменные - практически аналог C++'ного shared_ptr. Циклические ссылки разрываются аналогично (функция weaken превращает переменную в «weak_ptr»). Многие даже не задумываются, что GC нет.

Так в чем прикол «безопасного программирования» по Сану или Микрософту в таком случае?

Реклама для менеджеров от программирования. Процесс разработки ничего не выигрывает от наличия GC. Но в «бренд» вложено слишком много сил и времени, и все кто связался с GC будут продвигать его до последнего.

Возможно, лет через 10-15 оно все-таки сдохнет. Но не раньше, к сожалению.

anonymous
()
Ответ на: комментарий от Love5an

Ну и вывод примера, естественно:

Doing some work...
Doing some work...
Doing some work...
File contents:
Hello, world!
файл в итоге удаляется, да.

Love5an
()
Ответ на: комментарий от Love5an

Можно пойти даже еще дальше, и для каждого из ресурсов вести свой стек подчищения, но мне лень было писать такое, суть и так понятна.

Love5an
()
Ответ на: комментарий от anonymous

Тут нет ничего плохого. Где я говорил, что это полохо?

LamerOk ★★★★★
()
Ответ на: комментарий от anonymous

Дурак ты, дурак. Совсем неумный дурак.

anonymous
()
Ответ на: комментарий от Love5an

Если ты про оригинальный Lisp и его наследников - «это» не живет, а мучается. В любом случае это другая тема.

А под языками с GC почти всегда подразумеваются C# или Java. Если они оба загнутся - GC в mainstream не останется. Это вполне реально - их помаленьку вытесняют скриптовые языки.

anonymous
()
Ответ на: комментарий от den73

> если мы потеряли список из миллиона объектов без финализации, сборщик мусора ... обязан перебрать каждый объект из этого миллиона и вызвать для него пустой финализатор.

Не надо быть таким наивным и верить в ту святую простоту, что выдаёт анонимус. В ява у всех объектов есть тип, а для типа заранее известно, есть у него финализатор или нет.

LamerOk ★★★★★
()
Ответ на: комментарий от anonymous

> Это вполне реально - их помаленьку вытесняют скриптовые языки.

Ты говоришь это так, как будто в «скриптовых» языках нет GC. :3

LamerOk ★★★★★
()
Ответ на: комментарий от anonymous

> Культурный уровень лисперов поражает.

А чего тут удивительного? Всегда чувствовал, что от языков с GC программисты тупеют. Лисперы - самый наглядный тому пример.

anonymous
()
Ответ на: комментарий от LamerOk

> Ты говоришь это так, как будто в «скриптовых» языках нет GC. :3

Он не обязан в них быть. Пример - тот же Perl. Любой скриптовый язык можно «отучить» от GC без видимых изменений. Поэтому можно сделать вид что его нет ^__^

anonymous
()
Ответ на: комментарий от LamerOk

> В ява у всех объектов есть тип, а для типа заранее известно, есть у него финализатор или нет
Ну и прекрасно. В любом случае, если есть финализатор, то есть ещё одно действие при сборке мусора - копаться в мусоре в момент, когда он пролетает из рук владельца в сторону мусорного контейнера, и вызывать финализаторы. Я бы сказал, что у класса «пивная бутылка» есть финализатор, а у класса «пустой пластиковый пакет» нету. Поэтому бомж (или приравненный к нему сборщик мусора) копается в контейнере и вызывает финализатора для каждой пивной бутылки. Хотя эта аналогия не вполне точна. Более похожа ситуация, когда пластиковый пакет нужно помыть перед тем, как его выбросить, согласно природоохранному законодательству.

den73 ★★★★★
()
Ответ на: комментарий от Love5an

> Ну а лабы то сдал?

Ну а тебе то тупеть просто некуда.

Ты уж определись, что от меня хочешь ^__" А то пока ты только подтверждаешь мой диагноз.

Лабы все сдал уж лет 8 как. Программирую на С/C++ и Perl больше 10 лет. Даже не вспомню, когда последний раз встречал «утечки памяти», «двойные удаления» и прочие ужасы не-GC языков.

Так что мое мнение - GC не нужен. Те, кто не могут без него программировать - тоже не нужны.

anonymous
()
Ответ на: комментарий от anonymous

>И что тут плохого есть? Никаких указателей нет, сборщиков мусора нет. Всё само закрется и удалится.

Повторяю в четвертый раз: По какой причине быстрее это должно быть чем с GC? Если бы string создавался в стеке или .bss и как следствие был фиксированного размера, тогда да - конечно быстрее.

Absurd ★★★
()
Ответ на: комментарий от den73

> Более похожа ситуация, когда пластиковый пакет нужно помыть перед тем, как его выбросить, согласно природоохранному законодательству.

Между нами, девочками, финализаторы ты пишешь сам. Если ты моешь мусор, прежде чем его выкинуть, тебе некого винить, кроме себя.

LamerOk ★★★★★
()
Ответ на: комментарий от LamerOk

>> Более похожа ситуация, когда пластиковый пакет нужно помыть перед тем, как его выбросить, согласно природоохранному законодательству.

Между нами, девочками, финализаторы ты пишешь сам.

Джошуа Блох видел только одно применение финалайзерам - диагностика.

Absurd ★★★
()
Ответ на: комментарий от anonymous

Да ты вообще прямо лидер митол группы.

Сколько лет, 30?
И что, всё сам пишешь? Даже до должности архитектора не дошел? И всё на «C/C++» да перле? Я бы мог понять, если бы лисп какой-нибудь, или смоллтолк. На них убежденные т.н. хакеры и в 50 лет пишут.
Но на С++, да еще и в виде «C/C++» и перле(т.е. на «промышленных» языках, пик которых был лет 15 назад, и которые сейчас тихо помирают)? Т.е. еще и легаси какое-нибудь поддерживаешь? У меня для тебя плохие новости. Ты неудачник. А судя по тому, что лисп для тебя это откуда-то из параллельной реальности, то живешь ты где-нибудь в дикой провинции, т.е. неудачник в кубе. Ну, или, ты просто-напросто тупой и необразованный.

Love5an
()
Ответ на: комментарий от Absurd

> Джошуа Блох видел только одно применение финалайзерам - диагностика.

Для яваподобных - он прав на все 100.

LamerOk ★★★★★
()
Ответ на: комментарий от Love5an

Все не из столиц оказывается неудачники? Ну ты не только некультурный, но и законченый дебил. Твой диагноз полностью подтвержён.

anonymous
()
Ответ на: комментарий от anonymous

«Не из столицы» вообще говоря != Мухосранск(то, что я имел ввиду).
Но, видимо, насчет этого я угадал, раз тебя так задело, гыгы.

Love5an
()
Ответ на: комментарий от Love5an

Ты редкий дебил. Что с людьми лисп делает. Или ты уже слабоумным родился?

anonymous
()
Ответ на: комментарий от Love5an

Агитировать за что-либо (за лисп в данном случае) обсирая всех и вся вокруг могут только законченые дауны. Антирекламу лиспу делаешь хорошую на ЛОРе.

anonymous
()
Ответ на: комментарий от anonymous

>Агитировать за что-либо (за лисп в данном случае) обсирая всех и вся вокруг могут только законченые дауны. Антирекламу лиспу делаешь хорошую на ЛОРе.

но ведь в треде же раз пять объяснили, что управление памятью подсчётом ссылок почти всегда неэффективно. может в данном случае уже констатация факта происходит, а не «обсирательство»?

Кстати, выделением памяти тоже нужно управлять...

anonymous
()
Ответ на: комментарий от anonymous

Другого управления памятью не существует кроме подсчёта ссылок? Где тут подсчёт ссылок?

{
  vector<char> v;
  v.push_back(3);
}
{
  char[100] v;
  v[1] = 2;
}

anonymous
()
Ответ на: комментарий от anonymous

>Другого управления памятью не существует кроме подсчёта ссылок? Где тут подсчёт ссылок?

Во втором случае вообще нет управления памятью. А вектор тупо копирует содержимое.

anonymous
()
Ответ на: комментарий от anonymous

>vector<char> v; v.push_back(3);

Каким образом ты надеешься вернуть этот вектор вызывающему коду? Или это так, вектор в себе?

Absurd ★★★
()
Ответ на: комментарий от Love5an

Надо же, сколько ярлыков приклеил, на мне аж места не осталось >__<

Митол меня бесит, как и «удачники» - мажоры, пристроенные папой на теплое местечко. Возможно я «неудачник» в твоем одномерном представлении мира, но меня это нисколько не трогает.

Архитектор - не должность, а роль в проекте. Был в ней не раз, не очень понравилось. Надо думать, проектировать, делать прототипы, выбрасывать, снова делать, обсуждать, убеждать всю команду что надо именно так, слушать нытье и «рацпредложения» рядовых разработчиков, и так далее... Удовольствие на любителя.

15 лет назад компиляторы С++ не поддерживали шаблоны и STL. Какой там пик использования, это был совсем другой язык. А Perl 5 тогда и года не было. Пик их использования как раз сейчас. Актуальны они будут еще лет 10, а может и более.

Легаси не поддерживаю - у фирмы на это индусы есть, они дешевле.

Lisp - не из параллельной реальности, а из прошлого. Я был бы только рад если б он был поживее. Может быть, он бы задавил уебище XML вместе с его выблядками XPath и XSLT. Как же они меня достали, не описать просто.

anonymous
()
Ответ на: комментарий от anonymous

Подсчет ссылок в схеме с GC тоже есть. Иначе GC не сможет понять, что объект не используется.

Основное преимущество прямого подсчета ссылок - не скорость, а простота и «предсказуемость». Для программиста нет разницы - так зачем платить больше?

anonymous
()
Ответ на: комментарий от anonymous

>Для программиста нет разницы - так зачем платить больше?

и ведь не платят таким больше, или не?

anonymous
()
Ответ на: комментарий от Love5an

Каким местом, для этого конкретного случая(работа с файлом)(особенно «менее гибко»)?

Покажите мне пример работы с тремя файлами с with-open-file. Думаю - будет 3 уровня вложенности. Это менее читабельно и абсолютно не нужно. Мне лень смотреть справку на with-open-file, если вдруг она предусматривает много файлов, то пусть это будут файл, сокет и ещё что-нибудь. Пример искусственный, в большинстве случаев ресурс действительно один. Но в большинстве случаев и вложенность лишняя для файла не нужна.

Про лисп - спасибо за пример, я в принципе не сомневаюсь, что макросами в лиспе можно сделать много чего :) Про add-cleaner не совсем понял, зачем оно надо, ну ладно.

Legioner ★★★★★
()
Ответ на: комментарий от anonymous

Подсчет ссылок в схеме с GC тоже есть. Иначе GC не сможет понять, что объект не используется.

Вот только этот подсчёт осуществляется раз в несколько секунд (или когда там вызывается GC). А в случае прямого подсчёта ссылок - постоянно идёт инкремент-декремент, т.к. копирование ссылок - очень частая операция. Это, как минимум, засирание кеша процессора несущественными для программы данными, и скорее всего это заметно скажется на производительности.

Основное преимущество прямого подсчета ссылок - не скорость, а простота и «предсказуемость». Для программиста нет разницы - так зачем платить больше?

Так как вы будете решать вопрос циркулярных ссылок? Таки запускать изредка полный цикл GC? Или, как старый Internet Explorer - кушать память?

Legioner ★★★★★
()
Ответ на: комментарий от Love5an

Love5an хватит брызгать слюной. Мы уже поняли что являемся кубическими неудачниками в вакууме. Скажи лучше что нибудь умное по теме топика.

pathfinder ★★★★
()
Ответ на: комментарий от pathfinder

>Скажи лучше что нибудь умное по теме топика.

Хотя нет. Лучше помолчи.

pathfinder ★★★★
()
Вы не можете добавлять комментарии в эту тему. Тема перемещена в архив.