在 Java 中测量一段代码在运行时的内存使用情况,作为服务的持续功能

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

我有一个项目,需要能够测量以文本形式接收的函数的 CPU 和内存空间效率,并使用 Java 编译器 API 在运行时进行编译。

我正在使用 ThreadMXBean 来测量运行时间。有更好/更准确的方法吗?

ManagementFactory.getThreadMXBean().getCurrentThreadCpuTime();

我需要的是有关如何测量所用内存的建议。 理想情况下,我想了解每项作业及其大小。但我可以精确计算代码使用的字节数。

每一段代码都需要自动进行编译、测试、运行和评估。因此,使用 Profiler 并自行查看并不是一种选择。 欢迎您向我提供任何建议、可能的方法、资源或工具。

我需要澄清这一点。这不是一次性的过程。 它是网络应用程序的主要服务,可以实时接收、编译、分析和评分已实现的功能。在选择时,我预计会有 100 个并发作业正在进行。一次性监控或使用外部工具手动监控的过程不是我的目标。

我重复:我想这样做

as a service
。它不是为了测试我的应用程序或分析它们。

我不会咬人(或反对票,因为我们是这样的),所以任何认真的建议都会赢得赞成票。

状态更新:该项目已暂停,因为我没有可靠的方法来进行内存使用测量。我目前正在寻找 JVM 世界之外的其他语言/框架,它们也可以做到这一点。 即便如此,我仍在积极寻求建议和研究这个项目。

java runtime performance-testing runtime-compilation
2个回答
3
投票

我认为使用

ThreadMXBean
是实现这一目标的最佳方法,您可以获得所需的所有信息。

我们使用此代码片段来测量执行期间使用的最大内存:

    try {
        PrintWriter out = new PrintWriter(System.out);
        List<MemoryPoolMXBean> pools = ManagementFactory
                .getMemoryPoolMXBeans();
        for (MemoryPoolMXBean pool : pools) {
            MemoryUsage peak = pool.getPeakUsage();
            out.printf("Peak %s memory used: %,d%n", pool.getName(),
                    peak.getUsed());
            out.printf("Peak %s memory reserved: %,d%n", pool.getName(),
                    peak.getCommitted());
        }
        out.close();
    } catch (Throwable t) {
        System.err.println("Exception in agent: " + t);
    }

这里是 ManagementFactory 用例的有用资源。


1
投票

没有明确说明,但您的问题暗示所有函数将在同一个 jvm 中运行。

虽然为每个函数启动一个单独的 jvm 会增加开销,但我会认真考虑这个选项 - 它将使测量内存和 cpu 使用情况变得更加容易,因为您将能够使用开箱即用的 mx beans 来收集每个 jvm 统计信息并报告统计信息到控制过程。

您可能会发现您需要单独的 jvm 提供的隔离。

你能保证提供的函数不会导致无限循环吗?您能保证它们都不会耗尽所有可用内存或其他资源吗?单独的 jvm 将提供有效的沙箱。

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