查找java中的内存分配热点
我们的GC正在努力工作,我们希望减少一些暂停。 在使用实际的JVMGC参数之前或调整时,我们需要解决一些内存分配问题 我想知道哪些对象正在使GC工作:查找java中的内存分配热点,java,performance,memory-management,garbage-collection,jvm,Java,Performance,Memory Management,Garbage Collection,Jvm,我们的GC正在努力工作,我们希望减少一些暂停。 在使用实际的JVMGC参数之前或调整时,我们需要解决一些内存分配问题 我想知道哪些对象正在使GC工作: 有没有办法知道每次GC都会疏散哪些物体 他在工作吗 有没有办法知道哪些对象在它们之间移动 每次GC工作时的区域 有没有办法知道哪些物体在伊甸园区域 我正在广泛使用Jprofiler和内存分析器。 我希望获得有关我的登台环境中正在运行的应用程序的此信息 对于问题1,可以使用。这将允许您在对象被GC’ed(或可GC)时收到通知 至于另外两个,我不太清
至于另外两个,我不太清楚。在运行的JVM中查找内存分配可能需要很大的努力 相反,您可以在GC或分配时签出热点并添加自己的日志。编译您自己的热点并跟踪日志
使用
-XX:+printcomployment
可以帮助您
-XX:+printcomilation
标志输出如下所示:
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
对于2和3,您可以在应用程序的运行会话期间使用带有Oracle或OpenJDK
java
可执行文件的-XX:+PrintGCDetails
和-XX:+PrintGCTimeStamps
标志这将在日志中为我们提供此信息。OldGen空间的内容:您可以找到OldGen空间中驻留的对象。您需要在完全GC之前和之后打印直方图:-XX:+printClassHistogramBeforoullGC-XX:+printClassHistogramBeforfullGC
。由于YoungGen收集是在完整GC之前执行的,因此这些直方图将显示老一代的内容
检测提前升级的对象:要确定是否有任何实例提前升级,您需要研究直方图,查看哪些类应该驻留在OldGen
中,哪些类应该只在YoungGen
中看到。这不能自动完成,您需要对每个类及其实例的用途进行推理,以确定对象是否为临时对象
YoungGen/Eden空间的内容:我没有找到一种方法来区分哪些物体居住在伊甸园中。您可能知道,jProfiler和MemoryAnalyzer可以转储堆,但这不会告诉您对象驻留在哪个区域。但是,您也可以定期拍摄直方图快照,然后编写一个简单的脚本来解析输出并告诉您哪些实例增长最快,使用:
jmap-histo$pid
可用的最佳选项是最小化通过查找分配热点创建的对象。您还可以按类别查看保留的大小和数量,以确定要专注于哪些类别。跟踪分配不是更好的主意吗?我们试图找出的是哪些对象在年轻一代中幸存下来,并到达伊甸园或旧伊甸园,尽管它们是临时的。我如何在其中看到特定的对象信息?哪些课程正在被清除?它们在堆中停留了多少时间?不是特定的对象,而是总体对象行为,检查可视化工具建议和示例用例OK,这不是问题,我知道PrintGCDetails和SpringGCTimestamps,它们不是我要找的。听起来很有趣,我会试着去挖掘它,可能真的很难。我不确定finalize在这里是否有用,因为带有finalize方法的实例可能会在GC期间收集,也可能不会收集。这会严重扭曲分配/解除分配行为。