标定JVM内存消耗,类似于操作系统如何进行消耗

问题描述 投票:2回答:1

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

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

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

任何建议,最好只是代码,我们将不胜感激,但是如果它能够执行我要执行的任务,我也可以尝试一些软件。

java memory jvm benchmarking memory-profiling
1个回答
4
投票

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");

该方法返回总分配内存的一个近似值],但是这种近似值通常非常精确。

此外,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
}

如何运行:

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

-XX:+UseG1GC -XX:-UseTLAB选项来记录all

分配。否则,async-profiler将在采样模式下工作,仅记录一小部分分配。

这是输出的样子:

Allocation graph by async-profiler

© www.soinside.com 2019 - 2024. All rights reserved.