我们的GC正在努力工作,我们想要减少一些暂停。 我们在使用实际的JVM GC args进行调整之前或期间要解决一些内存分配问题。
我想知道哪些物品让GC出汗:
我正在与Jprofiler和Memory Analyzer广泛合作。 我想在我的暂存环境中获取有关正在运行的应用程序的此信息。
答案 0 :(得分:4)
对于2和3,您可以在应用程序的运行会话期间将-XX:+PrintGCDetails
和-XX:+PrintGCTimeStamps
标志与Oracle或OpenJDK java
可执行文件一起使用
答案 1 :(得分:2)
对于问题1,可以使用Phantom References。这将允许您在对象是GC(或GC能够)时收到通知。
至于其他两个,我不太清楚。
答案 2 :(得分:2)
在正在运行的JVM中查找内存分配可能需要付出很大努力。
相反,您可以结帐热点source code并在GC或分配时添加自己的日志。编译自己的热点并跟踪日志。
使用-XX:+PrintCompilation
可以帮助您。
-XX:+PrintCompilation
标志输出如下所示:
1 sb java.lang.ClassLoader::loadClassInternal (6 bytes)
2 b java.lang.String::lastIndexOf (12 bytes)
3 s!b java.lang.ClassLoader::loadClass (58 bytes)
标志对应于:
b Blocking compiler (always set for client)
* Generating a native wrapper
% On stack replacement
! Method has exception handlers
s Synchronized method
答案 3 :(得分:2)
我们可能会尝试使用一些字节代码检测来添加finalize(可能是Object),它会在日志中提供这些信息。
答案 4 :(得分:1)
OldGen空间的内容:您可以找到OldGen中的对象。您需要在Full GC之前和之后打印直方图:-XX:+PrintClassHistogramBeforeFullGC -XX:+PrintClassHistogramAfterFullGC
。由于YoungGen集合在Full GC之前执行,因此这些直方图将显示旧代的内容。
检测过早提升的对象:要确定是否提前提升了任何实例,您需要研究直方图以查看预期在OldGen
中应包含哪些类以及哪些类应该是仅在YoungGen
中看到。这不能自动完成,您需要推断每个类及其实例的目的,以确定该对象是否是临时的。
YoungGen / Eden空间的内容:我还没有找到一种方法来区分哪些物体存在,例如在伊甸园。您可能知道, jProfiler 和 MemoryAnalyzer 可以转储堆,但这不会告诉您对象所在的区域。但是,您也可以定期获取直方图快照,然后编写一个简单的脚本来解析输出并告诉您哪些实例增长最快,使用:jmap -histo $pid
。