One morning you wake up find out you have access to God’s developer console. What’s the first thing you do with this power?
Discussion
♦ 154 + W 479 & Share
^ BEST COMMENTS ▼
I like forks • 5h
hehe3301 • 7h
sudo rm -rf oceans/*/contents/
*.plástic
sudo rm -rf people/*/*.cáncer sudo rm -rf v
чем один вид отличается от другого
начинаешь работать, 99.9% ты даже не будешь трогать этот ебучий гц, и иногда будешь вызывать диспоуз, патерн скопипащенный с сайта масдая
Мне на вскидку приходит только:
Какие объекты собирает сборщик?
Почему финализаторы не есть гуд?
Сколько поколений у сборщика?
потому что конечная точка в приложении
3(2)
но я ответил не развернуто и можно еще очень долго доебываться
но зачем? какой блять в этом смысл?
двунаправленный список, есть ссылка на его начало, в списке два объекта, первый ссылается на второй, второй назад, убираем ссылку на начало, но элементы списка каждый имеют ссылку на себя от соседа и чо - не освобождать их? А нахрена такой GC вообще нужен?
У современных языков программирования нету подсчета ссылок и строится граф-достижимости из корня приложения. Т.е если 2 объекта где-то в космосе ссылаются друг на друга и нету ссылок на них из других частей, то объект грохается.
если я правильно понял, про что ты
в жабке есть параллельный с твоими трэдами гц и есть фуллгц, который всех, кроме себя, суспендит, пока работает. первый по-быстренькому выносит мусор из young generation, а второй уже достижимость из корня графа проверяет, но при этом stop the world
алсо, в новой яве как-то еще более хитро всё, но я пока не сильно погружался
Например, зная как работает GC ты не будешь много мусорить соединяя большое кол-во строк между собой, а будешь пользоваться StringBuilder'ом.
Т.е тоже самое можно сказать про структуры: Зачем знать структуры, когда все за тебя сделано? А вот зная, что список имеет такую-то сложность, а словарь такую-то, ты понимаешь, что лучше использовать словарь на большом кол-ве данных, а не список. Какой-нибудь новичок может обмазываться LINQ и думать, что Where работает так же быстро как в СУБД.
соединяя кучу строк ты тупо будешь ждать ... а это время,
а линкью ...а их много и они по разному работают
ты с этим познакомишься сам
и от гц ты дальше будешь знать что гц существует, не более
GC хорош для мелких задач, но когда ты используешь ресурсы по максимуму, то приходится самому управлять памятью (и не допускать до неё gc где это ненужно)
Ну хз на счет ресурсов. Если все правильно спроектировано, то память не должно не куда утекать.
Я не спорю, что ручной контроль памяти может работать шустрее, но важно его еще правильно реализовать, так как очистка памяти может вызывать фрагментацию и все такое. В .NET управляемая куча дефрагментируется и сжимается в фоне.
По сути, это вечный холивар, как Ручник VS Автоматическа коробка передач.
Решил погуглить, и в теме, за 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 - итератор не нужен.
Хотя сам по себе этот пример, конечно, не является поводом всегда где только можно отказываться от интерфейсов коллекций в пользу конкретного класса :) Часто семантика важнее, чем производительность.
< -> <
> -> >
Мухахаха! А кто сказал, что фоновым тредам достанется CPU раньше, чем кончится память? Взять любую практическую задачу типа компрессора или какого другого вычисления, алгоритм которых предусматривает постоянное выделение/освобождение памяти и тяжелое использование CPU.
Если конечно ты не создаешь системные хендлы о которых ничего неизвестно сборщику мусора.
А ответить? :-) Например, чем обеспечивается запуск GC *до* того момента, как память подходит к концу?
Выделялка памяти в .NET мониторит положение дел и если все плохо, то инициирует сборку мусора.
Во-вторых, аварийное завершение приложения из-за кривости GC абсолютно недопустимо и такой GC сразу идёт лесом вместе со всей системой разработки. И я не верю, что реальные системы так устроены.
статистика же есть. знаем, сколько памяти всего, знаем, сколько свободно осталось, остальное - мумор + всё нужное - про это тоже догадываемся.
при невозможности выделить память возникает эксепшен, можно залогироваться, перед тем как помереть. это будет после попытки пошуршать гц и что-нибудь освободить.
Именно что должно. Никакая реально используемая система управления памятью не вносит непрогнозируемых задержек на простом выделениях памяти, иначе её бы невозможно было использовать в реальных крупных приложениях.
А знать, сколько всего/сколько свободно осталось - совершенно недостаточно, потому как на самом деле надо знать, по какому адресу найдется свободный в данным момент блок нужного размера.
Про exception это тривиальности. Суть в том, что если система кидает exception в то время, когда реально в куче полно уже не нужного, но ещё не высвобожденного мусора, то это негодная система. И если она во время выделения памяти начинает заниматься обходом дерева и высвобождением структур, это тоже негодная система.
и плюс, пока ты своей софтине выдал адекватный объём оперы, оно так и работает - как почти rt.
проблемы начнутся только когда или мало выделенно, или память течет.
и даже в этом случае проблем меньше - помрёт тольео косячная программа, а не все подряд
Между настоящим realtime и требованиями к скорости управления памятью в "обычных" системах есть разница, и требования эти всё равно есть, типа O(1) или O(log(log n)) или в крайнем случае O(log n) для времени выделения памяти в зависимости от количества уже аллоцированных объектов. Никому не нужна система, которая тратит O(n) или даже O (n*log n) времени на это, чтобы обойти свои структуры и их перестроить.
> мало выделенно
А что значит "мало выделенно" и чем этот подход отличается от говно-привычки считать, что память бесконечна?
потому что она большую часть времени выделяет память быстро. и только когда идёт бесконтрольный отжор памяти - всё равно есть косяк, всё равно надо чинить - тогда она тормозит
память не бесконечна - ок
а сколько ее?
640кб хватит всем?
я могу прогу запустить на тачке с гигом оперы, а могу с терабайтом.
настраивать ты всё равно будешь некий кусок, чонть типа размера кэшей, и плюс есть некий минимальный объём оперы, необходимый для нормальной работы, о котором тебе в мане тестировщик напишет.
на практике нет никакой разницы, отдаёшь ли ты память оси сразу понемногу, или большими кусками, или не отдаешь вообще, в случае когда ты ее сразу же попросишь назад.
если у тебя за каждым байтиком очередь желающих стоит его поюзать - всё колом встанет, какой-то процент оперы должен валяться без дела про запас, ничего с этим не поделаешь
На самом деле нет - система, которая тратит O(n) времени на выделение памяти, не выделяет память быстро "большую часть времени". Ты вообще понимаешь обозначение O(n)? Это значит, что время на выделение памяти под очередной объект, прямо пропорционально количеству уже созданных объектов. Это охренительно медленно и пользователи не захотят пользоваться таким "продуктом". Как уже говорилось, быстро это когда время O(1) - не зависит от количества ранее созданных объектов, ну или хотя бы O(log(log n)), растёт очень слабо.
> минимальный объём оперы, необходимый для нормальной работы, о котором тебе в мане тестировщик напишет.
Не тестировщик должен определять этот размер памяти, а алгоритм и программист, а GC не должен ему мешать. Почему-то на системах без GC не требуются ключики -Xms/Xmx.
это важно только в системах реального времени, где жесткие требования по гарантиям. но такие системы обычно писец тормозные, там методично кладут болт на среднюю скорость в угоду гарантиям скорости отклика.
доёб к Xms/Xmx не ясен
для прог без гц Xms=0, Xmx=всё что есть
на практике скорее наоборот
короче все что не входит в работу компилятора и он не может никак повлиять на это
только тогда для этого надо вызвать 1 метод и забыть про него
а юзинг это сахар что бы вызвать сборщик мусора автоматом
Например, у тебя какой-то хендл системы и GC про него ничего не знает. Так вот, Dispose и финализатор- это то место, где с ними можно разобраться.
https://www.codejourney.net/2018/09/net-internals-08-what-about-large-object-heap-loh/
Т.е. как и всегда проблема не в технологии а в прокладке
разница только в том, вся ли это память компа, или лимит, отданный виртуалке
ты наверн не в курсе,что RC - говно, сочетающее в себе плохую предсказуемость пауз как у гц, и геморрой освобождения сложных графов объектов, как при ручном менеджменте
Разумеется, речь не идёт об идиотах, которые при любом раскладе раскидываются памятью, как бесконечным ресурсом.
ну и не всегда это просто глупость. у одного были резоны типа "ну ты ж ресурс, ты его и освобождай", а у другого "кроме тебя этот ресурс никому не нужен - ты его и освобождай"
"есть контроль" - это тока звучит красиво. в реальной большой проге большинству надо по рукам давать за попытки лезть, куда не надо, ограничивать этот самый контроль до минимума, иначе будет жопа
Идиотов всегда больше, это не аргумент для того, чтобы утверждать, что так и надо
большинству реально больших прог нужен механизм, который бы обеспечивал, что пока программист делает всё правильно, то потребление памяти у проги не растёт на пустом месте из-за того, что GC не справляется
гц перестаёт справляться, когда выжрана большая часть памяти - а это явно не было запланировано. уже косяк.
ты в курсе, что, например, жабе ты на старте выделяешь лимит оперы? она может его сразу отъесть весь, а потом, по мере надобности, выделяет под свои объекты. ну на самом деле она чутка поумнее, и сразу всё не отъедает, и даже может вернуть часть памяти назад оси.
А вот так. Ещё раз повторяю вопрос: чем обеспечивается, что одновременно и память выделяется быстро, и tracing GC как в Java вообще получит возможность начать работу до того, как память кончится?
> ты в курсе, что, например, жабе ты на старте выделяешь лимит оперы?
В курсе :-) -Djava.awt.headless=true -Xms1024m -Xmx1024m -XX:+UseConcMarkSweepGC
но еще раз: если до такого дошло, значит уже какая-то хуйня в проге. и решения 2: или выделяй больше оперы в следующий раз, или фикси свой говнокод. тюнингом гц это решается прям очень редко когда