package com.arturmkrtchyan.sizeof4j.util; import com.arturmkrtchyan.sizeof4j.MemoryLayout; import com.arturmkrtchyan.sizeof4j.SizeOfException; import sun.misc.Unsafe; import java.lang.management.ManagementFactory; import java.lang.management.MemoryPoolMXBean; import java.lang.management.RuntimeMXBean; import java.lang.reflect.Field; import java.util.List; public class JvmUtil { private static final String ARCH_32 = "32"; private static final String ARCH_64 = "64"; private static final long HEAP_30GB = 30L * 1024 * 1024 * 1024; private static Unsafe unsafe; private JvmUtil() {} ////////////////////////////////////////// ///////////// VM Properties ////////////// ////////////////////////////////////////// public static String vmName() { return System.getProperty("java.vm.name"); } public static String vmVersion() { return System.getProperty("java.vm.version"); } public static String vmSpecVersion() { return System.getProperty("java.vm.specification.version"); } public static String vmArch() { return System.getProperty("sun.arch.data.model"); } //////////////////////////////////////// ///////////// JRE Properties /////////// //////////////////////////////////////// public static String jreSpecVersion() { return System.getProperty("java.specification.version"); } public static String jreVersion() { return System.getProperty("java.version"); } //////////////////////////////////////// ////////////// OS Properties /////////// //////////////////////////////////////// public static String osArch() { return System.getProperty("os.arch"); } //////////////////////////////////////// ////////////// Memory Usage /////////// ////////////////////////////////////// /** * Represents the initial amount of memory (in bytes) that the Java virtual machine requests from * the operating system for memory management during startup. * The Java virtual machine may request additional memory from the operating system and may also * release memory to the system over time. * The value of init may be undefined. * * @return memory */ public static long initialMemory() { long memory = 0; for (MemoryPoolMXBean mp : ManagementFactory.getMemoryPoolMXBeans()) { memory += mp.getUsage().getInit(); } return memory; } /** * Represents the amount of memory currently used (in bytes). * * @return memory */ public static long usedMemory() { long memory = 0; for (MemoryPoolMXBean mp : ManagementFactory.getMemoryPoolMXBeans()) { memory += mp.getUsage().getUsed(); } return memory; } /** * Represents the amount of memory (in bytes) that is guaranteed to be available for use by the Java virtual machine. * The amount of committed memory may change over time (increase or decrease). * * @return memory */ public static long committedMemory() { long memory = 0; for (MemoryPoolMXBean mp : ManagementFactory.getMemoryPoolMXBeans()) { memory += mp.getUsage().getUsed(); } return memory; } /** * Represents the maximum amount of memory (in bytes) that can be used for memory management. * Its value may be undefined. The maximum amount of memory may change over time if defined. * The amount of used and committed memory will always be less than or equal to max if max is defined. * * @return memory */ public static long maxMemory() { long memory = 0; for (MemoryPoolMXBean mp : ManagementFactory.getMemoryPoolMXBeans()) { memory += mp.getUsage().getMax(); } return memory; } public static String processId() { String runtimeName = ManagementFactory.getRuntimeMXBean().getName(); return runtimeName.split("@")[0]; } public static synchronized Unsafe unsafe() { if(unsafe == null) { try { Field field = Unsafe.class.getDeclaredField("theUnsafe"); field.setAccessible(true); unsafe = (Unsafe) field.get(null); } catch (Exception e) { throw new SizeOfException(e); } } return unsafe; } public static MemoryLayout memoryLayout() { return memoryLayout(vmArch()); } protected static MemoryLayout memoryLayout(final String vmArch) { if(ARCH_32.equals(vmArch)) { return MemoryLayout.Layout32; } else if(ARCH_64.equals(vmArch)) { if(maxMemory() > HEAP_30GB || isCompressedOopsDisabled()) { return MemoryLayout.Layout64; } return MemoryLayout.LayoutCoops; } return null; } public static List<String> getInputArguments() { RuntimeMXBean bean = ManagementFactory.getRuntimeMXBean(); return bean.getInputArguments(); } private static boolean isCompressedOopsDisabled() { return isOptionPresent("-XX:-UseCompressedOops"); } protected static boolean isOptionPresent(final String option) { List<String> arguments = getInputArguments(); for(String argument : arguments) { if(argument.equals(option)) { return true; } } return false; } // List of properties // http://docs.oracle.com/javase/6/docs/api/java/lang/System.html#getProperties%28%29 // Memory Usage // http://docs.oracle.com/javase/7/docs/api/java/lang/management/MemoryUsage.html }