I do not know how to get exactly the boundaries of the young and old generations (I'm not even sure that this is possible). In the case of G1, this became even more complicated because it allowed more than one region of the old generation to be available due to the unusual structure of the G1 heap.
But you can use complex heuristics to determine if an object is in the old generation or not, not knowing the boundaries of generations.
Let us use the secret knowledge of black magic about the inside of hotspot : each object contains a heading with all the necessary information about the lock, the hashcode identifier and the most important, age . Extracting age will look like this:
return unsafe.getByte(targetObject, 0L) & 0x78;
where 0x78 is the corresponding mask in the object header for its age (bits from the 4th to the 7th inclusive).
Get the MaxTenuringThreshold control API parameter:
MBeanServer server = ManagementFactory.getPlatformMBeanServer(); HotSpotDiagnosticMXBean bean = ManagementFactory.newPlatformMXBeanProxy( server, "com.sun.management:type=HotSpotDiagnostic", HotSpotDiagnosticMXBean.class); int threshold = Integer.valueOf(bean.getVMOption("MaxTenuringThreshold").getValue());
Now you know the age and life threshold of your application, so you can assume that if age is greater than the threshold, it is in the old generation.
Note: This is a heuristic based on magic and secret knowledge.
- This will not work if someone synchronizes with the target while you read it, because the VM will move the title onto the stack and replace the title with a pointer to the stack
- It will not work with
XX:+UseAdaptiveSizePolicy , so you must explicitly disable it. - Some object can be selected directly in the old generation (for example, because of its size).
- Type I error .
- This approach is illegal, unsafe and may be incorrect and jvm dependent
source share