Правда о выделении памяти в java
2) Один экземпляр класса Number должен занимать 8байт,
Проблема в том, что это только вершина айсберга.
В реальных приложениях все горазда хуже, что заставило рассмотреть
простейший пример и даже на нем обнаружить большую несостыковку.
тут где-то был , в котором обсуждалось, что память свободную и занятую трудно считать. в Java это тоже трудно.
Ваши комментарии?во-первых, Number занимает больше чем 8байт.
во-вторых, при добавлении двух int-ов на самом деле может добавиться или больше, или меньше, из-за выравнивания.
Это обусловлено в том числе тем, что некоторые gc гораздо лучше работают при наличии свободной памяти.
Например, в этом случае коллектору young/old generations совсем не нужно вызывать full gc, который занимает ну очень много времени.
Уверен, если ты выделишь ровно столько памяти, сколько требуется (ну, плюс ещё мегабайт 50 то со скрипом твоя программа пройдёт, но выполняться будет медленней. Вообще политика брать столько памяти, сколько дают, она в целом верная....
Ps +1 к проблеме оценке памяти в яве. Да и вызов System.gc вовсе не гарантирует вызова коллектора.
Дальше я вроде пишу: "допустим не 8байт ..." Опять приходим к противоречию.Так откуда ты знаешь, какими блоками выделяется память? Вполне возможен вариант, когда куча увеличивается скачками, например, по 64М.
что память увеличивается скачками по ~89Mb, что объясняет
основную массу забираемой памяти…
Но это к сожалению не объясняет изначальной проблемы,
присутствующей в реальной аппликации, где размер ява-машины
в десятки раз превышает все разумные пределы, профайлер памяти
в этом случае оказывается бесполезным, т.к. показывает скажем 100Mb
в качестве shallow size объектов, в то время как MemUsage=1600Mb
значит утечка где-то в нативной либе, или на стыке java и натив, а не в самой джаве
профайлер памятиУ тебя что-то не так. Shallow size - это какой shallow size?
в этом случае оказывается бесполезным, т.к. показывает скажем 100Mb
в качестве shallow size объектов, в то время как MemUsage=1600Mb
В чем цель исследования? Узнать sizeof объекта или понять систему управления памятью в JVM?
а должна быть 100Mb не болше...
Shallow size - это какой shallow size?См. jProfiler. Размер всех полей объекта - самих ссылок, а не того на что они ссылаются...
(что должен подтвердить опыт других) и с чистой душой начать все переписывать на C++
А ты на С++ запусти и выполни параллельно рандомное освобождение и выделение больших блоков и убедись, что С++ еще более для таких задач не подходит. Если у тебя большое количество маленьких объектов, то их нужно заменять на семейство массивов (или коллекций, умеющих эффективно хранить примитивные типы) - и тогда памяти будет тратится столько, сколько нужно.
Оставить комментарий
Zusk
Правду предстоит выяснить.Возьмем простейшую программу, создающую длинный однонаправленный список:
Концовка запуска:
free=3006Kb i=9900000
free=2903Kb i=10000000
total created=10000000 total free=190085Kb
Смотрим в Process Viewer:
MemUsage=182Mb VMSize=227Mb
Это означает:
1) В ходе создания списка из 10 млн. элементов java выделила
как минимум 190Mb где-то на свои внутренние нужды, и эту память
потом успешно освободил gc.
2) Один экземпляр класса Number должен занимать 8байт,
все объекты – 80Mb, на деле имеем в разы больше.
Допустим яве надо хранить что-то еще и Number занимает больше 8байт.
тогда добавляем в него еще два поля типа int
в расчете что размер используемой памяти увеличится ровно на 80Mb.
На это раз получаем:
MemUsage=281Mb VMSize=442Mb
Видим, что разница на десятки Mb больше чем надо.
Ваши комментарии?