Например?
Мне на вскидку приходит только:
Какие объекты собирает сборщик?
Почему финализаторы не есть гуд?
Сколько поколений у сборщика?
Мне на вскидку приходит только:
Какие объекты собирает сборщик?
Почему финализаторы не есть гуд?
Сколько поколений у сборщика?
на которых нету ссылок
потому что конечная точка в приложении
3(2)
но я ответил не развернуто и можно еще очень долго доебываться
но зачем? какой блять в этом смысл?
потому что конечная точка в приложении
3(2)
но я ответил не развернуто и можно еще очень долго доебываться
но зачем? какой блять в этом смысл?
> на которых нету ссылок
двунаправленный список, есть ссылка на его начало, в списке два объекта, первый ссылается на второй, второй назад, убираем ссылку на начало, но элементы списка каждый имеют ссылку на себя от соседа и чо - не освобождать их? А нахрена такой GC вообще нужен?
двунаправленный список, есть ссылка на его начало, в списке два объекта, первый ссылается на второй, второй назад, убираем ссылку на начало, но элементы списка каждый имеют ссылку на себя от соседа и чо - не освобождать их? А нахрена такой GC вообще нужен?
Это в старых реализация GC такое было.
У современных языков программирования нету подсчета ссылок и строится граф-достижимости из корня приложения. Т.е если 2 объекта где-то в космосе ссылаются друг на друга и нету ссылок на них из других частей, то объект грохается.
У современных языков программирования нету подсчета ссылок и строится граф-достижимости из корня приложения. Т.е если 2 объекта где-то в космосе ссылаются друг на друга и нету ссылок на них из других частей, то объект грохается.
А что такое "корень приложения"? Если основной тред долгоиграющего сервиса по разным событиям рожает и запускает ещё треды работать параллельно, создавая собственные объекты, причём "папе" нет дела до работы детишек - папе всё равно копить бесконечно растущий список ссылок на детишек? А если нет, то при удалении ссылки на дитятко его объекты для GC становятся "без ссылок" с точки зрения родителя и всё дитятко надо зачистить, что ли?
Ну запустил ты треды. Треды же выполняю конкретно какой-то метод. => тут 2 ситуации: Ты создаешь объекты в рамках этого метода и при выходе из некоторой области видимости этого объекта они удаляются или ты создаешь объекты и заносишь их в поля класса, который создал эти треды, т.е корня классу, который прикреплен к корню.
Ну хз. Как мне кажется, поверхностные знания работы GC должны иметься.
Например, зная как работает GC ты не будешь много мусорить соединяя большое кол-во строк между собой, а будешь пользоваться StringBuilder'ом.
Т.е тоже самое можно сказать про структуры: Зачем знать структуры, когда все за тебя сделано? А вот зная, что список имеет такую-то сложность, а словарь такую-то, ты понимаешь, что лучше использовать словарь на большом кол-ве данных, а не список. Какой-нибудь новичок может обмазываться LINQ и думать, что Where работает так же быстро как в СУБД.
Например, зная как работает GC ты не будешь много мусорить соединяя большое кол-во строк между собой, а будешь пользоваться StringBuilder'ом.
Т.е тоже самое можно сказать про структуры: Зачем знать структуры, когда все за тебя сделано? А вот зная, что список имеет такую-то сложность, а словарь такую-то, ты понимаешь, что лучше использовать словарь на большом кол-ве данных, а не список. Какой-нибудь новичок может обмазываться LINQ и думать, что Where работает так же быстро как в СУБД.
то что ты перечислил с гц никак не пересекается
соединяя кучу строк ты тупо будешь ждать ... а это время,
а линкью ...а их много и они по разному работают
ты с этим познакомишься сам
и от гц ты дальше будешь знать что гц существует, не более
соединяя кучу строк ты тупо будешь ждать ... а это время,
а линкью ...а их много и они по разному работают
ты с этим познакомишься сам
и от гц ты дальше будешь знать что гц существует, не более
Ну хз. Я бы если на работу принимал бы, то спросил бы все равно базис про ГЦ.
Вот такие "программисты" с поверхностными знаниями потом и выпускают "продукты", которые на практике своей требухой занимают всю доступную память, полагаясь на волшебный GC.
гц-среды при траблах внутри себя хотя бы всю ось не крашат
Я могу придумать 101 вопрос по сборщику мусора. Как писал ещё Джоэл Спольски - все нетривиальные абстрации дырявы. По крайней мере в C#, есть куча вопросов с боксингом переменных. А ещё есть mono, в котором свой, тупейший gc.
GC хорош для мелких задач, но когда ты используешь ресурсы по максимуму, то приходится самому управлять памятью (и не допускать до неё gc где это ненужно)
GC хорош для мелких задач, но когда ты используешь ресурсы по максимуму, то приходится самому управлять памятью (и не допускать до неё gc где это ненужно)
По моему, боксинг переменных в C# давно исчерпал себя. Когда не было дженериков, то с ним можно было столкнуться. Так же можно было столкнуться, когда не было nullable типов. Теперь не представляю, как в современном C# можно с ним пересечься, если кто-то специально себе в ноги не стреляет и не пишет убогий код.
Ну хз на счет ресурсов. Если все правильно спроектировано, то память не должно не куда утекать.
Я не спорю, что ручной контроль памяти может работать шустрее, но важно его еще правильно реализовать, так как очистка памяти может вызывать фрагментацию и все такое. В .NET управляемая куча дефрагментируется и сжимается в фоне.
По сути, это вечный холивар, как Ручник VS Автоматическа коробка передач.
Ну хз на счет ресурсов. Если все правильно спроектировано, то память не должно не куда утекать.
Я не спорю, что ручной контроль памяти может работать шустрее, но важно его еще правильно реализовать, так как очистка памяти может вызывать фрагментацию и все такое. В .NET управляемая куча дефрагментируется и сжимается в фоне.
По сути, это вечный холивар, как Ручник VS Автоматическа коробка передач.
Dictionary<Enum, object> в Mono будет боксить енумы. Познай всю боль программистов на юинити.
Бляяя. Я тока щяс узнал, что в этом случае enum будет box-иться.
Решил погуглить, и в теме, за 2017 говорилось, что можно в качестве ключа юзать не "enum", а "ScriptableObject".
Кто может подсказать, насколько это лучше, чем обычный int?
Решил погуглить, и в теме, за 2017 говорилось, что можно в качестве ключа юзать не "enum", а "ScriptableObject".
Кто может подсказать, насколько это лучше, чем обычный int?
var list = new List<string>{"test"};
foreach(var str in in list){
Console.WrilteLine(str);
}
var ilist = (IList<string>)list;
foreach(var str in in ilist){
Console.WrilteLine(str);
}
(код написал по памяти - могут быть синтаксические ошибки)
Почему в первом случае foreach работает без аллокаций, а во втором случае с аллокацией? Как избежать аллокаций во втором случае? =)
В первом случае вызовется
List.Enumerator List.GetEnumerator()
который вернёт value-тип - переменная будет лежать в стеке метода.
Во втором это будет
IEnumerator IEnumerable.GetEnumerator()
который вернёт такой же List.Enumerator, только забоксенный в IEnumerator - отсюда аллокация.
Избежать можно итерируясь циклом for вместо foreach - итератор не нужен.
Хотя сам по себе этот пример, конечно, не является поводом всегда где только можно отказываться от интерфейсов коллекций в пользу конкретного класса :) Часто семантика важнее, чем производительность.
List.Enumerator List.GetEnumerator()
который вернёт value-тип - переменная будет лежать в стеке метода.
Во втором это будет
IEnumerator IEnumerable.GetEnumerator()
который вернёт такой же List.Enumerator, только забоксенный в IEnumerator - отсюда аллокация.
Избежать можно итерируясь циклом for вместо foreach - итератор не нужен.
Хотя сам по себе этот пример, конечно, не является поводом всегда где только можно отказываться от интерфейсов коллекций в пользу конкретного класса :) Часто семантика важнее, чем производительность.
P.S. Никогда не доводилось писал код с генериками здесь в комментах: сожрались параметры в угловых скобках на типах List, IEnumerable и IEnumerator. Не знаю, как их правильно можно экранировать, было бы здорово узнать.
обычное хтмл-экранирование
< -> <
> -> >
< -> <
> -> >
> в фоне
Мухахаха! А кто сказал, что фоновым тредам достанется CPU раньше, чем кончится память? Взять любую практическую задачу типа компрессора или какого другого вычисления, алгоритм которых предусматривает постоянное выделение/освобождение памяти и тяжелое использование CPU.
Мухахаха! А кто сказал, что фоновым тредам достанется CPU раньше, чем кончится память? Взять любую практическую задачу типа компрессора или какого другого вычисления, алгоритм которых предусматривает постоянное выделение/освобождение памяти и тяжелое использование CPU.
Ну так память ты выделяешь через CLR => CLR осведомлена о каждом твоем шаге и может спокойно инициировать сборку мусора.
Если конечно ты не создаешь системные хендлы о которых ничего неизвестно сборщику мусора.
Если конечно ты не создаешь системные хендлы о которых ничего неизвестно сборщику мусора.
На практике не имеет значение, что теоретически может инициировать CLR. На практике имеет значение, как конкретно достигается то, что GC успевает освобождать неиспользуемую уже память быстрее, чем она кончается физическая память. Потому что если у GC нет возможности успевать это делать, то вся идея GC идёт лесом - ровно с тем же успехом можно вообще ничего не высвобождать и надеяться, что оперативки хватит до завершения работы процесса, а там уж операционка всё приберёт.
> Я могу придумать 101 вопрос по сборщику мусора
А ответить? :-) Например, чем обеспечивается запуск GC *до* того момента, как память подходит к концу?
А ответить? :-) Например, чем обеспечивается запуск GC *до* того момента, как память подходит к концу?
за GC зарплатой отвечал =)
OK, повторю вопрос тебе: чем обеспечивается одновременно быстрая работа процедуры выделения памяти и то, что GC успевает освобождать неиспользуемую память быстрее, чем она переполняет физическую RAM?
Triggering a GC when appropriate: The allocator triggers a GC when the allocation budget (a threshold set by the collector) is exceeded or when the allocator can no longer allocate on a given segment.
Выделялка памяти в .NET мониторит положение дел и если все плохо, то инициирует сборку мусора.
Выделялка памяти в .NET мониторит положение дел и если все плохо, то инициирует сборку мусора.
Тем, что все твои NEW вызывают CLR, а она содержит некоторый регистр объектов => может перед выделением памяти попытаться сделать очистку. Если это не поможет, то приложение аварийно завершается.
Во-первых, нельзя делать очистку перед выделением памяти в синхронном режиме (с ожиданием, когда же GC провернётся), потому что проход по графу ссылок и вычистка операция дорогая (долгая), а выделение памяти должно выполняться быстро.
Во-вторых, аварийное завершение приложения из-за кривости GC абсолютно недопустимо и такой GC сразу идёт лесом вместе со всей системой разработки. И я не верю, что реальные системы так устроены.
Во-вторых, аварийное завершение приложения из-за кривости GC абсолютно недопустимо и такой GC сразу идёт лесом вместе со всей системой разработки. И я не верю, что реальные системы так устроены.
ничо никому не "должно" выделяться быстро. особенно когда ты не дал софтине достаточно памяти и она затыкается в гц постоянно.
статистика же есть. знаем, сколько памяти всего, знаем, сколько свободно осталось, остальное - мумор + всё нужное - про это тоже догадываемся.
при невозможности выделить память возникает эксепшен, можно залогироваться, перед тем как помереть. это будет после попытки пошуршать гц и что-нибудь освободить.
статистика же есть. знаем, сколько памяти всего, знаем, сколько свободно осталось, остальное - мумор + всё нужное - про это тоже догадываемся.
при невозможности выделить память возникает эксепшен, можно залогироваться, перед тем как помереть. это будет после попытки пошуршать гц и что-нибудь освободить.
Все что IDisposable обертываешь в using. Говнокодил как-то на Delphi - так и не понял, как там нормально и красиво высвобождать ресурсы.
в шарпе вызывается сборщик мусора тогда когда есть подлючение к базам, с работой с директориями
короче все что не входит в работу компилятора и он не может никак повлиять на это
только тогда для этого надо вызвать 1 метод и забыть про него
а юзинг это сахар что бы вызвать сборщик мусора автоматом
короче все что не входит в работу компилятора и он не может никак повлиять на это
только тогда для этого надо вызвать 1 метод и забыть про него
а юзинг это сахар что бы вызвать сборщик мусора автоматом
using не вызывает сборщик мусора, он лишь позволяет закрыть неуправляемые ресурсы, которые могут потеряться при сборке мусора.
Например, у тебя какой-то хендл системы и GC про него ничего не знает. Так вот, Dispose и финализатор- это то место, где с ними можно разобраться.
Например, у тебя какой-то хендл системы и GC про него ничего не знает. Так вот, Dispose и финализатор- это то место, где с ними можно разобраться.
В C# важно знать не сколько про поколения (за 10 лет работы ни разу не понадобилось на практике), сколько про деление GC на SOH и LOH. Про SOH обычно все все знают, но LOH тоже важно понимать.
https://www.codejourney.net/2018/09/net-internals-08-what-about-large-object-heap-loh/
https://www.codejourney.net/2018/09/net-internals-08-what-about-large-object-heap-loh/
Это если не работать с хайлоадом. Бо в нем ебли с гц и его тюнингом(как из кода, так и настройками) хватает.
Dispose к GC не имеет никакого отношения.
С точки зрения юзера, либо все GC жуткое говно, либо в природе практически не существует программистов, умеющих правильно писать на языках со встроенными GC. Потому что пухнет это говно ничуть не меньше, чем из-за тривиальных утечек в других продуктах, а частенько resident size именно для таких "продуктов" получается в разы толще.
Прикол в том, что если тех, у кого течет память с GC, посадить за языки без GC то у них прога ебанется ещё на старте, пожрав все ресурсы.
Т.е. как и всегда проблема не в технологии а в прокладке
Т.е. как и всегда проблема не в технологии а в прокладке
Так это хорошо! Чем раньше всё наворачивается, тем больше шансы, что проблема будет отлажена ещё до релиза. Хуже всего это заметать проблемы под ковёр коллектором.
Ну так даже в системах с GC нужно следить за неуправляемыми ресурсами, так как GC ничего неизвестно о хендлах, которые ты запрашиваешь у ОС. Т.е пока ты юзаешь управляемые объекты, все ок, а когда тебе нужно через WinAPI какую-то штуку проделать, то будь добр не забыть вызвать функцию освобождения ресурсов.
Да причём тут внешние ресурсы, это всё тривиальности ты расписываешь. Я вообще не понимаю, как на практике GC может *эффективно* освобождать обычную память без постоянного таскания в своей требухе огромной кучи уже протухшего мусора и откуда берутся гарантии того, что память не кончится раньше, чем GC вообще получит возможность начать работу.
а такие гарантии разве есть в не-гц системах?
в при управлении памятью без GC у программиста есть *возможность* явно отдавать память куче, с тем чтобы при следующих выделениях она могла быть переиспользована сразу же, без запроса новой памяти у операционки
гарантий тоже никаких нет, память может закончиться внезапно что там, что там.
разница только в том, вся ли это память компа, или лимит, отданный виртуалке
разница только в том, вся ли это память компа, или лимит, отданный виртуалке
Ты не понял, о чём речь. Для ясности, возьмём Perl - в нём нету tracing GC как в Java, но и нету явного управления памятью по типу malloc/free, и всё равно нет утечек. Объект высвобождается сразу как пропадает последняя ссылка на него (reference-counted GC), а проблема циклических ссылок решается при помощи "слабых ссылок" (weak references). И всё прекрасно.
В сравнении с тем же прикладным алгоритмом, но с ручным высвобождением памяти, когда у программиста есть контроль над кучей.
Разумеется, речь не идёт об идиотах, которые при любом раскладе раскидываются памятью, как бесконечным ресурсом.
Разумеется, речь не идёт об идиотах, которые при любом раскладе раскидываются памятью, как бесконечным ресурсом.
а почему речь не идет об идиотах? их больше
ну и не всегда это просто глупость. у одного были резоны типа "ну ты ж ресурс, ты его и освобождай", а у другого "кроме тебя этот ресурс никому не нужен - ты его и освобождай"
"есть контроль" - это тока звучит красиво. в реальной большой проге большинству надо по рукам давать за попытки лезть, куда не надо, ограничивать этот самый контроль до минимума, иначе будет жопа
ну и не всегда это просто глупость. у одного были резоны типа "ну ты ж ресурс, ты его и освобождай", а у другого "кроме тебя этот ресурс никому не нужен - ты его и освобождай"
"есть контроль" - это тока звучит красиво. в реальной большой проге большинству надо по рукам давать за попытки лезть, куда не надо, ограничивать этот самый контроль до минимума, иначе будет жопа
*ресурс выделил
> а почему речь не идет об идиотах? их больше
Идиотов всегда больше, это не аргумент для того, чтобы утверждать, что так и надо
Идиотов всегда больше, это не аргумент для того, чтобы утверждать, что так и надо
> в реальной большой проге большинству
большинству реально больших прог нужен механизм, который бы обеспечивал, что пока программист делает всё правильно, то потребление памяти у проги не растёт на пустом месте из-за того, что GC не справляется
большинству реально больших прог нужен механизм, который бы обеспечивал, что пока программист делает всё правильно, то потребление памяти у проги не растёт на пустом месте из-за того, что GC не справляется
как гц может не справляться, если всё сделано правильно?
гц перестаёт справляться, когда выжрана большая часть памяти - а это явно не было запланировано. уже косяк.
ты в курсе, что, например, жабе ты на старте выделяешь лимит оперы? она может его сразу отъесть весь, а потом, по мере надобности, выделяет под свои объекты. ну на самом деле она чутка поумнее, и сразу всё не отъедает, и даже может вернуть часть памяти назад оси.
гц перестаёт справляться, когда выжрана большая часть памяти - а это явно не было запланировано. уже косяк.
ты в курсе, что, например, жабе ты на старте выделяешь лимит оперы? она может его сразу отъесть весь, а потом, по мере надобности, выделяет под свои объекты. ну на самом деле она чутка поумнее, и сразу всё не отъедает, и даже может вернуть часть памяти назад оси.
> как гц может не справляться, если всё сделано правильно?
А вот так. Ещё раз повторяю вопрос: чем обеспечивается, что одновременно и память выделяется быстро, и tracing GC как в Java вообще получит возможность начать работу до того, как память кончится?
> ты в курсе, что, например, жабе ты на старте выделяешь лимит оперы?
В курсе :-) -Djava.awt.headless=true -Xms1024m -Xmx1024m -XX:+UseConcMarkSweepGC
А вот так. Ещё раз повторяю вопрос: чем обеспечивается, что одновременно и память выделяется быстро, и tracing GC как в Java вообще получит возможность начать работу до того, как память кончится?
> ты в курсе, что, например, жабе ты на старте выделяешь лимит оперы?
В курсе :-) -Djava.awt.headless=true -Xms1024m -Xmx1024m -XX:+UseConcMarkSweepGC
Да на каком языке вы говорите?!
господи, каменты божественны. напомнило времена, когда в интернет детей не пускали...
Чтобы написать коммент, необходимо залогиниться
чем один вид отличается от другого
начинаешь работать, 99.9% ты даже не будешь трогать этот ебучий гц, и иногда будешь вызывать диспоуз, патерн скопипащенный с сайта масдая