我可以通过编程方式找出实例所在的 GC 代吗?
这个问题的范围仅限于HotSpot 世代。有没有什么方法可以以编程方式找出特定实例生活在哪一代。数据例如:
- 年轻一代还是老一代?
- 如果年轻,哪个幸存者空间?
- 在 TLAB 内?哪个线程?
任何技术(例如,BTrace、JVMTI) 只要我能做这样的事情就可以工作:
Object x = new Object();
HotSpotGenerationInfo info = HotSpotGenerationUtil.getInfo(x);
乞丐不能成为选择者,但理想情况下我也可以了解感兴趣的实例何时从一代中转移到另一个在它发生的时刻(即,基于事件回调——对轮询中隐含的延迟和开销不感兴趣。)
对没有理由地说“不”的答案不感兴趣:)
This question is limited in scope to HotSpot generations. Is there any way to programmatically find out in which generation a particular instance lives. Data such as:
- Young or old generation?
- If young, which survivor space?
- Inside TLAB? Which thread?
Any technique (ex., BTrace, JVMTI) works so long as I can do something like this:
Object x = new Object();
HotSpotGenerationInfo info = HotSpotGenerationUtil.getInfo(x);
Beggars can't be choosers but ideally I could also learn when the instance of interest was being moved from one generation to another at the moment it happens (i.e., event callback based -- not interested in the delay & overhead implicit in polling.)
Not interested in answers that just say "no" without justification :)
如果你对这篇内容有疑问,欢迎到本站社区发帖提问 参与讨论,获取更多帮助,或者扫码二维码加入 Web 技术交流群。
绑定邮箱获取回复消息
由于您还没有绑定你的真实邮箱,如果其他用户或者作者回复了您的评论,将不能在第一时间通知您!
发布评论
评论(2)
据我所知,你不能直接查询对象当前所在的内存池。但是,通过垃圾收集运行,对象会被提升到不同的内存池,并且你可以查询自VM以来运行的major/minor gc的次数开始使用 JMX。如果您在创建对象时另外记录这些计数器,则可以重建该对象所在的池中是否存在 GC。
As far as I know, you can not directly query which memory pool an object currently lives in. However, objects are promoted to a different memory pool by a garbage collection run, and you can query the number of major/minor gc runs since VM start using JMX. If you additionally take note of these counters when the object is created, you can reconstruct whether there was a GC since and from that which pool the object lives in.
“计算自对象创建以来的 GC 次数”方法还有一个额外的复杂性 - 它没有考虑过早的对象升级。
如果幸存者空间基本上太小,并且来自 Eden 的内存压力(即对象至少存活一次的比率)很高,那么对象将在达到完整的长期保留阈值之前被提升为长期保留。
在实际示例中,健康的应用程序通常具有非零百分比的过早升级。事实上,0% 的过早升级率是一个非常糟糕的信号 - 它表明你的幸存者空间太大了,而且你正在浪费大量内存。
There's an additional complication to the "count the number of GCs since the object was created" approach - it doesn't take into account premature object promotion.
If the survivor spaces are basically too small, and memory pressure from Eden (ie the rate of objects surviving at least once) is high, then objects will be promoted to tenured before they hit the full tenuring threshold.
In real examples, healthy applications will typically have non-zero percentages of premature promotion. In fact, a 0% premature promotion rate is a really bad sign - it says that your survivor spaces are much, much too big and you're wasting a lot of memory.