Бенчмаркинг потребления памяти JVM аналогично тому, как это делается в ОС - PullRequest
2 голосов
/ 01 мая 2020

При попытке сравнить определенный метод c относительно того, сколько объектов создано и сколько байтов они занимают во время работы этого метода, в Android можно сделать это:

Debug.resetThreadAllocCount()
Debug.resetThreadAllocSize()
Debug.startAllocCounting()
benchmarkMethod()
Debug.stopAllocCounting()
var memoryAllocCount = Debug.getThreadAllocCount()
var memoryAllocSize = Debug.getThreadAllocSize()

Теперь я хотел бы протестировать тот же метод, но в обычном настольном приложении, где эти методы недоступны. Я не нашел ничего подобного, и любой другой код тестирования производительности, который я пробовал, не дает согласованных результатов, как приведенный выше код, который дает одинаковый результат каждый раз, когда запускается один и тот же тест.

Любое предложение Желательно, чтобы был признателен только код, однако я был бы готов попробовать и некоторое программное обеспечение, если оно способно выполнить задачу, которую я пытаюсь выполнить.

1 Ответ

4 голосов
/ 01 мая 2020

ThreadMXBean.getThreadAllocatedBytes может помочь:

com.sun.management.ThreadMXBean bean =
        (com.sun.management.ThreadMXBean) ManagementFactory.getThreadMXBean();
long currentThreadId = Thread.currentThread().getId();

long before = bean.getThreadAllocatedBytes(currentThreadId);
allocatingMethod();
long after = bean.getThreadAllocatedBytes(currentThreadId);

System.out.println("Allocated " + (after - before) + " bytes");

Метод возвращает приближение общего объема выделенной памяти, но обычно это приближение довольно точное.

Кроме того, asyn c -profiler имеет Java API для профилирования распределений. Он не только подсчитывает, сколько объектов выделено, но также показывает точные выделенные объекты со следами стеков сайтов выделения.

public static void main(String[] args) throws Exception {
    AsyncProfiler profiler = AsyncProfiler.getInstance();

    // Dry run to skip allocations caused by AsyncProfiler initialization
    profiler.start("alloc", 0);
    profiler.stop();

    // Real profiling session
    profiler.start("alloc", 0);

    allocatingMethod();

    profiler.stop();
    profiler.execute("file=alloc.svg");  // save the output to alloc.svg
}

Как запустить:

java -Djava.library.path=/path/to/async-profiler -XX:+UseG1GC -XX:-UseTLAB Main

* Для записи всех выделений требуется 1018 * опций. В противном случае asyn c -profiler будет работать в режиме выборки, записывая только небольшую часть выделений.

Вот как будет выглядеть вывод:

Allocation graph by async-profiler

...