java - 与 Android 操作系统类似,对 JVM 内存消耗进行基准测试

标签 java memory jvm benchmarking memory-profiling

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

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

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

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

最佳答案

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选项来记录所有分配。否则,async-profiler 将在采样模式下工作,仅记录一小部分分配。

输出如下:

Allocation graph by async-profiler

关于java - 与 Android 操作系统类似,对 JVM 内存消耗进行基准测试,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/61539760/

相关文章:

python - 在 Python 中表示图灵机的无限磁带的最有效方法是什么?

c - 迭代存储在堆上的数组

java - 是否必须将引用设置为 null 才能使垃圾收集工作

java - 如何在 java applet 中使用 JMF 功能?

java - Spring MVC JSP JSTL 退出每个带有 boolean 值的循环

java - 使用 UI 在后台运行 sphinx4 识别器

performance - 是否可以使用 ETW(Windows 事件跟踪)来收集内存统计信息?

java - 静态变量如何在类加载时获取对象的值?

java - 以编程方式捕获 Full GC 计数

java - 静态方法在类加载时是否创建对象