对 JVM 内存消耗进行基准测试,类似于 Android 操作系统的做法

Sty*_*kis 2 java memory benchmarking jvm memory-profiling

当尝试对特定方法进行基准测试时,关于创建了多少对象以及在该方法运行时它们占用了多少字节,在 Android 中可以这样做:

Debug.resetThreadAllocCount()
Debug.resetThreadAllocSize()
Debug.startAllocCounting()
benchmarkMethod()
Debug.stopAllocCounting()
var memoryAllocCount = Debug.getThreadAllocCount()
var memoryAllocSize = Debug.getThreadAllocSize()
Run Code Online (Sandbox Code Playgroud)

我现在想对相同的方法进行基准测试,但在这些方法不可用的普通桌面应用程序上。我没有发现任何类似的东西,我尝试过的任何其他内存基准测试代码都没有提供一致的结果,就像上面的代码一样,每次运行相同的基准测试时都会给出完全相同的结果。

任何建议,最好只是代码将不胜感激,但是如果它能够执行我正在尝试做的任务,我也愿意尝试一些软件。

apa*_*gin 5

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");
Run Code Online (Sandbox Code Playgroud)

该方法返回的近似总分配的存储器的,但这种近似通常是相当精确的。

此外,async-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
}
Run Code Online (Sandbox Code Playgroud)

如何运行:

java -Djava.library.path=/path/to/async-profiler -XX:+UseG1GC -XX:-UseTLAB Main
Run Code Online (Sandbox Code Playgroud)

-XX:+UseG1GC -XX:-UseTLAB需要选项来记录所有分配。否则,async-profiler 将在采样模式下工作,只记录一小部分分配。

下面是输出的样子:

异步分析器的分配图