I don't know how to get exactly the borders of young and old generations (not even sure it's possible). In case of G1 it became even more complicated because it's allowed to have more than one old generation region due to unusual heap structure of G1.
But you can use tricky heuristic to determine whether object is in old generation or not without knowing borders of generations.
Let's use some black magic secret knowledge about hotspot internals: every object contains header with all necessary information about locking, identity hashcode, and most important, age.
Extracting age will look like this:
return unsafe.getByte(targetObject, 0L) & 0x78;
where 0x78 is corresponding mask in object header for its age (bits from 4th to 7th inclusive).
Obtain MaxTenuringThreshold
parameter via Management API:
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 object's age and tenuring threshold of your application, so you can assume that if age is greater than threshold, it's in old generation.
WARNING:
It's heuristic based on magic and secret knowledge.
- It will not work, if someone will synchronize on target object while you are reading it's age, because VM will move header to stack and replace header with pointer to stack
- It will not work with
XX:+UseAdaptiveSizePolicy
, so you should explicitly disable it.
- Some object can be allocated straight in old generation (e.g. because of it's size)
- Type I error prone
- This approach is illegal, unsafe and might be incorrect and jvm dependent