Измерение использования памяти определенной структуры данных

Я пытаюсь измерить использование памяти моей собственной структурой данных в моем приложении Tomcat Java EE на разных уровнях использования.

Чтобы измерить использование памяти, я попробовал две стратегии:

  1. Время выполнения freeMemory и totalMemory:

    System.gc(); //about 20 times
    long start = Runtime.getRuntime().freeMemory();
    
    useMyDataStructure();
    
    long end = Runtime.getRuntime().freeMemory();
    
    System.out.println(start - end);
    
  2. 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, это прекрасно работает для меня.

Другие вопросы по тегам