What GC parameters is a JVM running with?

2019-01-13 07:02发布

问题:

I'm still investigating issues I have with GC tuning (see prior question), which involves lots of reading and experimentation.

Sun Java5+ JVMs attempt to automatically select the optimal GC strategy and parameters based on their environment, which is great, but I can't figure out how to query the running JVM to find out what those parameters are.

Ideally, I'd like to see what values of the various GC-related -XX options are being used, as selected automatically by the VM. If I had that, I could have a baseline to begin tweaking.

Anyone know to recover these values from a running VM?

回答1:

Check out the HotSpotDiagnosticMBean

The following example will print out the value of an option as well as whether the value is DEFAULT or VM_CREATION:

import java.lang.management.ManagementFactory;

import javax.management.ObjectName;
import javax.management.openmbean.CompositeData;
import javax.management.openmbean.CompositeDataSupport;

public class HotSpotTest {

    public static void main(String [] args) throws Exception {
        printHotSpotOption("MaxHeapFreeRatio");
        printHotSpotOption("SurvivorRatio");
        printHotSpotOptions();
    }

    private static void printHotSpotOption(String option) throws Exception {
        ObjectName name = new ObjectName("com.sun.management:type=HotSpotDiagnostic");
        String operationName = "getVMOption";
        Object [] params = new Object [] {option};
        String [] signature = new String[] {String.class.getName()};
        Object result = ManagementFactory.getPlatformMBeanServer().invoke(name, operationName, params, signature);
        CompositeDataSupport data = (CompositeDataSupport) result;

        System.out.println(option);
        System.out.println("- Value: "+data.get("value"));
        System.out.println("- Origin: "+data.get("origin"));
    }

    private static void printHotSpotOptions() throws Exception {
        ObjectName name = new ObjectName("com.sun.management:type=HotSpotDiagnostic");
        String attributeName = "DiagnosticOptions";
        Object result = ManagementFactory.getPlatformMBeanServer().getAttribute(name, attributeName);
        CompositeData [] array = (CompositeData[]) result;
        for (CompositeData d : array) {
            System.out.println(d.get("name"));
            System.out.println("- Value: "+d.get("value"));
            System.out.println("- Origin: "+d.get("origin"));
        }
    }
}


回答2:

-XX:+PrintCommandLineFlags Prints flags passed on command line or configured by the ergonomics (auto-sizing) features.

-XX:+PrintFlagsInitial Dumps ALL the default flags and values.

-XX:+PrintFlagsFinal Dumps ALL the flags after processing command line and ergonomics.

So I think the latter will do for you, just add it to your command line script.



回答3:

Ideally, I'd like to see what values of the various GC-related -XX options are being used, as selected automatically by the VM. If I had that, I could have a baseline to begin tweaking.

It's not usually straightforward to deduce the exact heap configuration just from the command line flags supplied.

If your need is to know the heap configuration and you are in a non-Windows environment you can use jmap -heap like explained in this blog entry.

Here is a sample of the information provided:

    using parallel threads in the new generation.
    using thread-local object allocation.
    Concurrent Mark-Sweep GC

    Heap Configuration:
       MinHeapFreeRatio = 40
       MaxHeapFreeRatio = 70
       MaxHeapSize      = 1073741824 (1024.0MB)
       NewSize          = 268435456 (256.0MB)
       MaxNewSize       = 268435456 (256.0MB)
       OldSize          = 805306368 (768.0MB)
       NewRatio         = 7
       SurvivorRatio    = 6
       PermSize         = 21757952 (20.75MB)
       MaxPermSize      = 88080384 (84.0MB)


回答4:

You can use JMX for that. Kick off JConsole, and it should be displayed under the VM Summary tab. It should display all the arguments that have been passed to the JVM.

To do it programatically, you can refer to another SO answer: How to get vm arguments from inside of java application?



回答5:

If you're looking for a quick and easy human-readable tool, jconsole might be your friend here. Specifically, I'm looking at the "VM Summary" tab on my currently running FindBugs process and I see these details:

Current heap size: 788,720 kbytes

Maximum heap size: 932,096 kbytes

Committed memory: 923,648 kbytes

Pending finalization: 0 objects

Garbage collector: Name = 'PS MarkSweep', Collections = 324, Total time spent = 12 minutes

Garbage collector: Name = 'PS Scavenge', Collections = 1,132, Total time spent = 1 minute

Obviously, jvisualvm will give you related details but it doesn't seem to be quite as tightly focused on your specific needs (i.e., quickly readable details on the garbage collector).