Measuring memory use of a piece of code at runtime in Java as an on-going functionality of a service

589 Views Asked by At

I have a project where I need to be able to measure the efficiency in CPU and in memory space of functions I receive as text and compile at run-time using the Java Compiler API.

I am using ThreadMXBean to measure running time. Is there a better/more exact way?

ManagementFactory.getThreadMXBean().getCurrentThreadCpuTime();

What I need is advice on how to measure the memory used. Ideally I would like to know about every assignment, and its size. But I would be alright with a precise count of the bytes used by the code.

Every piece of code need to be compiled, tested, run and evaluated automatically. So using a Profiler and look yourself is not an option. Any suggestion, possible method, resource or tools you might point me to is welcome.

I need to make that point clear. This is not a one off process. It is the main service of a web app that receives, compiles, analyzes and scores implemented functions on the fly. At pick I would expect a few 100 concurrent jobs going on. The process of monitoring once or manually with external tools is not my goal.

I repeat: I want to do this as a service. It is not for testing my apps or profiling them.

I do not bite (or down-vote since we are on SO), so any serious suggestion will earn up-votes.

status update: This project is on hold since I do not have a solid reliable way of doing the memory use measurements. I am currently looking at other languages/frameworks out of the JVM world that could this too. Even so I am still actively seeking advice and studying for this project.

2

There are 2 best solutions below

5
On

I think using ThreadMXBean is the best way to achieve this, you can get all the info you need.

We are using this snippet to mesure the max memory used during an execution:

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

Here is a usefull ressource for ManagementFactory use case.

2
On

It is not clearly stated, but it is implied in your question that the all functions will be running within the same jvm.

Although launching a separate jvm per function adds overhead I would seriously consider this option - it would make measuring memory and cpu usage much easier as you would be able to use the out of the box mx beans that collect per jvm stats and report stats back to the controlling process.

You may find that you need the isolation separate jvms provide.

Can you guarantee that none of the supplied functions will result in an infinite loop? Can you guarantee that none of them will exhaust all available memory or some other resource? Separate jvms would provide an effective sandbox.