Измерение использования памяти определенной структуры данных
Я пытаюсь измерить использование памяти моей собственной структурой данных в моем приложении Tomcat Java EE на разных уровнях использования.
Чтобы измерить использование памяти, я попробовал две стратегии:
Время выполнения freeMemory и totalMemory:
System.gc(); //about 20 times long start = Runtime.getRuntime().freeMemory(); useMyDataStructure(); long end = Runtime.getRuntime().freeMemory(); System.out.println(start - end);
MemoryPoolMXBean.getPeakUsage ():
long before = Runtime.getRuntime().totalMemory() - Runtime.getRuntime().freeMemory(); List<MemoryPoolMXBean> memorymxbeans = ManagementFactory.getMemoryPoolMXBeans(); for(MemoryPoolMXBean memorybean: memorymxbeans){ memorybean.resetPeakUsage(); } useMyDataStructure(); for(MemoryPoolMXBean memorybean: memorymxbeans){ MemoryUsage peak = memorybean.getPeakUsage(); System.out.println(memorybean.getName() + ": " + (peak.getUsed() - before)); }
Метод 1 не выводит надежные данные вообще. Данные бесполезны.
Метод 2 выводит отрицательные значения. Кроме того, это getName()
говорит мне, что это выводит Code Cache
, PS Eden Space
, PS Survivor Space
а также PS Old Gen
отдельно.
Как я могу получить несколько последовательных номеров использования памяти до и после моего useMyDataStructure()
звонить в Java? Я не хочу использовать VirtualVM, я предпочитаю ловить номер в long
возразить и записать его в файл самостоятельно.
Заранее спасибо.
редактировать 1:
useMyDatastructure
в приведенных выше примерах была попытка упростить код. Что на самом деле там:
int key = generateKey();
MyOwnObject obj = makeAnObject();
MyContainerClass.getSingleton().addToHashMap(key, obj);
По сути, я действительно пытаюсь измерить, сколько памяти HashMap<Integer, MyOwnObject>
в MyContainerClass
принимает. Я буду использовать это измерение памяти для проведения эксперимента, в котором я заполняю экземпляры HashMap и MyOwnObject.
2 ответа
1-й из всех размеров объектов в Java нетривиален (как хорошо объяснено здесь).
если вы хотите узнать размер конкретного объекта, есть как минимум 2 библиотеки с открытым исходным кодом, которые сделают все за вас - java.sizeof и javabi-sizeof
Теперь, что касается вашего конкретного теста - System.gc() в основном игнорируется современными (горячими точками) jvms, независимо от того, сколько раз вы его вызываете. также возможно ли ваше useMyDataStructure()
метод не сохраняет ссылку на объект (ы), который он создает? в этом случае измерение свободной памяти после вызова не годится, поскольку любые выделенные объекты могли быть очищены.
Вы можете попробовать https://github.com/jbellis/jamm, это прекрасно работает для меня.