Ну подожди, как бы проблема то не в том, что нужен физический доступ к памяти - физической памяти в OS давно уже нет, вся память виртуальная. Проблема в том, что OS управляет ресурсами, и эффективное управление ресурсами подразумевает, что их можно быстро выделять и быстро убивать. Что делает неудобными языки с GC для системных задач. Ну т.е. процесс сдох - нужно, чтобы ресурсы освободились прямо сейчас, а не когда-нибудь.
Это собственно и претензия к Java для системного программирования - почти все более-менее RT программы на ней написаны в таком же стиле - что GC никогда не вызывается, т.е. с управлением памятью почти вручную.
Я, возможно, крамольную мысль сейчас выскажу, но мне сама концепция GC кажется удалением гланд через анальное отверстие. В моей картине мира настоящий прорыв случится тогда, когда появится аллокатор с таким алгоритмом, что GC потеряет смысл, поскольку занятые ресурсы будут высвобождаться по окончанию использования by design. Возможно, я идеалист.
Насколько я себе представляю реальность, необходимость в пробеге GC возникает, если процесс теряет выделенную ему память и не дохнет при этом, right? Потому как если сдохнет, всё, что он навыделял, аллокатор по идее должен освободить (если не освобождает, то значит, я наивный оптимист, но тем проще).
Таким образом, чтобы память не терялась, достаточно в потроха компилятора заложить обращение с выделенной памятью как с инодами (когда число линков становится равным 0, блок освобождается) - это повлечёт за собой сравнительно небольшие накладные расходы, и как мне представляется, сильно меньшие, чем необходимость гонять GC по кругу с определённой периодичностью, пусть даже GC ходит не по всей памяти (всё равно для нагруженных систем, именно тогда, когда ресурсы важны, ходить придётся практически по всей).
> Таким образом, чтобы память не терялась, достаточно в потроха компилятора заложить обращение с выделенной памятью как с инодами Про циклические ссылки Вы забыли.
Надо сказать, что в jvm gc достаточно умный, чтобы то, что по выходу из scope имеет счетчик ссылок 0 - удалять именно так, как Вам нравится.
А еще надо сказать, что gc еще выполняет функции дефрагментатора, что на компилятор хрен повесишь.
Это повлечет за собой сравнительно небольшие расходы на каждое копирование-удаление ссылки, что внутри какого-нибудь цикла может оказаться очень дорого.
Ну очевидно такого никогда не будет, т.к. есть структуры где удаление зависит от факторов вне контроля программы.
Допустим есть такая штука как поисковый кэш, он имеет фиксированный размер, как только он достигается что-то надо грохнуть, что именно грохнуть это некая простая логика, которая зависит от свойств потока поисковых запросов, но ее внутрь программы впишет только тот кто понимает, что происходит вне программы. Ну т.е. банально выбор между MFU и LRU это уже то что программа сделать не может.
Но GC да это реально странная штука, т.к. от утечек памяти оно не освобождает, в смысле достаточно забыть лишний элемент в структуре типа Set или Map и все приехали.
В ядре ОС есть мааааленький кусочек, который занимается приборкой за процессами и огромная куча кода, который к этому никакого отношения не имеет и только malloc()/free() дергает.
Просто прибирать надо не только за процессами и не только когда процесс дохнет, наверное мало приятного если память у всех процессов и самого ядра будет пухнуть как сейчас у java программ, или время от времени будет случаться stop world
Слушай, ну о чем ты вообще? Память процессов это совершенно отдельная штука, это ресурс который процессу отдается/забирается и к gc самого ядра отношения не имеет. Там и сейчас, фактически, идет сборка мусора при завершении процесса, да еще и хитрая, т.к. эти страницы обычно делятся с дисковым кешем. А выделение памяти для нужд самого ядра можно сделать множеством разных способов, stop world при сборке необязателен, распухание тоже. Собственно, в некоторых подсистемах ядра и так уже реализован reference counting gc, взять хотя бы сетевые буфера во FreeBSD.
Ну просто чем в этом в java и .net помогают тогда не понятно, в c ты вызывал free, в c++ delete, а тут ссылки зануляешь. Если что-то из этого забудешь все равно все взорвется.
Ты так говоришь, будто у тебя есть очень дорогая ссылка, ты ее бережно хранишь, и настраиваешь ссылаться то на одно, то на другое. Надоела - выкинь ее, да и дело с концом. Совсем на халяву проскочить не получится, но количество проблем снижается в разы по сравнению с ручным управлением памятью. Собственно, уже даже в c++ им никто не занимается, только сборщик там очень примитивный, через счетчики.
На самом деле (особенно с точки зрения обсуждаемого прикольного текста) физическая память в OS есть -- хоть "через функцию", но всё равно есть. Когда тебе надо сказать устройству, куда ему делать DMA считанных данных, надо использовать физические адреса. И тут, если что напутать, может получится неприятно -- хоть на Java пиши, хоть на чем.
Это собственно и претензия к Java для системного программирования - почти все более-менее RT программы на ней написаны в таком же стиле - что GC никогда не вызывается, т.е. с управлением памятью почти вручную.
Reply
Reply
Это в ряде мест похерит производительность. Зачастую занятые ресурсы можно высвобождать все разом, что значительно быстрее, нежели по отдельности.
Reply
Таким образом, чтобы память не терялась, достаточно в потроха компилятора заложить обращение с выделенной памятью как с инодами (когда число линков становится равным 0, блок освобождается) - это повлечёт за собой сравнительно небольшие накладные расходы, и как мне представляется, сильно меньшие, чем необходимость гонять GC по кругу с определённой периодичностью, пусть даже GC ходит не по всей памяти (всё равно для нагруженных систем, именно тогда, когда ресурсы важны, ходить придётся практически по всей).
Reply
Про циклические ссылки Вы забыли.
Надо сказать, что в jvm gc достаточно умный, чтобы то, что по выходу из scope имеет счетчик ссылок 0 - удалять именно так, как Вам нравится.
А еще надо сказать, что gc еще выполняет функции дефрагментатора, что на компилятор хрен повесишь.
Reply
Reply
Допустим есть такая штука как поисковый кэш, он имеет фиксированный размер, как только он достигается что-то надо грохнуть, что именно грохнуть это некая простая логика, которая зависит от свойств потока поисковых запросов, но ее внутрь программы впишет только тот кто понимает, что происходит вне программы. Ну т.е. банально выбор между MFU и LRU это уже то что программа сделать не может.
Но GC да это реально странная штука, т.к. от утечек памяти оно не освобождает, в смысле достаточно забыть лишний элемент в структуре типа Set или Map и все приехали.
Reply
хороший GC эффективнее даже ручных алгоритмов.
Reply
Reply
Reply
А выделение памяти для нужд самого ядра можно сделать множеством разных способов, stop world при сборке необязателен, распухание тоже. Собственно, в некоторых подсистемах ядра и так уже реализован reference counting gc, взять хотя бы сетевые буфера во FreeBSD.
Reply
Reply
Совсем на халяву проскочить не получится, но количество проблем снижается в разы по сравнению с ручным управлением памятью. Собственно, уже даже в c++ им никто не занимается, только сборщик там очень примитивный, через счетчики.
Reply
Reply
Reply
Reply
Leave a comment