简体   繁体   English

Jmap 堆转储,是否包括年轻代?

[英]Jmap heap dump, does it include young generation?

Quick question快速提问

Does the jmap heap dump include only the old generation, or also the young generation ? jmap 堆转储只包括老年代,还是年轻代?


Long explanation长解释

I have 2 heap dump ( jmap -heap:format=b 9999 ) :我有 2 个堆转储( jmap -heap:format=b 9999 ):

  • one of my server with no load (no HTTP request)我的一台服务器没有负载(没有 HTTP 请求)
  • one while working 50% CPU, a high load (benchmarking)一个同时工作 50% CPU,高负载(基准测试)

Now, the first dump shows a heap size bigger than the second (which I thought was weird).现在,第一个转储显示的堆大小比第二个大(我认为这很奇怪)。

Could that be because the Young generation (at high load) is changing often because the Garbage collector is running often (yes, the JVM is almost full) ?这可能是因为垃圾收集器经常运行(是的,JVM 几乎已满),因此年轻代(高负载)经常更改? Old generation is full at 99%, I've noticed the young generation space usage vary a lot.老年代已满 99%,我注意到年轻代空间使用情况差异很大。

So that would mean that I made the second dump right after the GC did his job, this is why its size is smaller.所以这意味着我在 GC 完成他的工作后立即进行了第二次转储,这就是为什么它的大小更小。 Am I right ?我对吗 ?

Additionnal informations :附加信息

Java args : Java参数:

-XX:+UseParallelGC -XX:+AggressiveHeap
-Xms2048m -Xmx4096m -XX:NewSize=64m
-XX:PermSize=64m -XX:MaxPermSize=512m

Quick Answer快速回答

Both - The Heap is made up of the Young and Old Generation.两者 - 堆由年轻代和年老代组成。 So when you take a heap dump, the contents contains both.因此,当您进行堆转储时,内容包含两者。 The Stats of the heap dump should be seperated.堆转储的统计信息应该是分开的。 Try removing the binary portion of your command and look at it in plain text.尝试删除命令的二进制部分并以纯文本形式查看它。 You will see a summary of your configuration, and then a break down of each generation.您将看到配置摘要,然后是每一代的细分。 On the flip side, a -histo would just show all objects on the heap with no distinction另一方面, -histo 只会显示堆上的所有对象,没有区别

Long Answer长答案

It could be that a garbage collection had just finished for the 2nd process.可能是第二个进程的垃圾收集刚刚完成。 Or the opposite, the first process may not have had a full collection in a while and was sitting at higher memory.或者相反,第一个进程可能已经有一段时间没有完整的收集并且处于更高的内存中。 Was this application/server just restarted when you took the capture?捕获时此应用程序/服务器是否刚刚重新启动? If you look at an idle process using a tool like jvisualvm , you will see the memory allocation graphs move up and down even though your process isn't doing any work.如果您使用jvisualvm类的工具查看空闲进程,即使您的进程没有做任何工作,您也会看到内存分配图上下移动。 This is just the JVM doing its own thing.这只是JVM在做自己的事情。

Typically your Full GC should kick off well before it reaches a 99% mark in the Old Gen. The JVM will decide when to run the full GC.通常,您的 Full GC 应该在 Old Gen 达到 99% 标记之前就开始。JVM 将决定何时运行 full GC。 Your Young Gen will fluctuate alot as this is where objects are created/removed the fastest.您的 Young Gen 会波动很大,因为这是创建/删除对象最快的地方。 There will be many partial GC's done to clean out the young gen before a full GC get run.在完整的 GC 运行之前,将有许多部分 GC 来清除年轻代。 The difference between the two will mean a pause in your JVM activity.两者之间的差异意味着您的 JVM 活动会暂停。 Seeing a partial GC will not hurt your application.看到部分 GC 不会损害您的应用程序。 But the pause times of a full GC will stop your application while it runs.但是完整 GC 的暂停时间会在您的应用程序运行时停止它。 So you will want to minimize those the best you can.因此,您将希望尽可能减少这些。

If you are looking for memory leaks or just profiling to see how your application(s) gc is working, I would recommend using the startup flags to print the garbage collection stats.如果您正在寻找内存泄漏或只是分析以查看您的应用程序 gc 是如何工作的,我建议您使用启动标志来打印垃圾收集统计信息。

-XX:+PrintGCDetails -verbose:gc -Xloggc:/log/path/gc.log

run your program for a while and then load the captured log in a tool to help visualize the results.运行您的程序一段时间,然后将捕获的日志加载到工具中以帮助可视化结果。 I personally use the Garbage Collection and Memory Visualizer offered in the IBM Support Assistant Workbench.我个人使用 IBM Support Assistant Workbench 中提供的Garbage Collection and Memory Visualizer It will provide you with a summary of the captured garbage collection stats as well as a dynamic graph which you can use to see how the memory in your application has been behaving.它将为您提供捕获的垃圾收集统计信息的摘要以及动态图,您可以使用它来查看应用程序中的内存行为。 This will not give you what objects were on your heap.这不会给你什么对象在你的堆上。

At problem times in your application, if you can live with a pause, I would modify your jmap command to do the following在您的应用程序出现问题时,如果您可以暂停一下,我会修改您的 jmap 命令以执行以下操作

jmap -dump:format=b,file=/file/location/dump.hprof <pid>

Using a Tool like MAT , you will be able to see all of the objects, leak suspects, and various other stats about the generations, references of the heap.使用像MAT这样的工具,您将能够查看所有对象、泄漏嫌疑人以及有关代代、堆引用的各种其他统计信息。

Edit For Tuning discussion编辑调整讨论

Based on your start-up parameters there are a few things you can try根据您的启动参数,您可以尝试一些操作

  • Set your -Xms equal to the same value as your -Xmx.将 -Xms 设置为与 -Xmx 相同的值。 By doing this the JVM doesn't have to spend time allocating more heap.通过这样做,JVM 不必花时间分配更多的堆。 If you expect your application to take 4gb, then give it all right away如果您希望您的应用程序占用 4GB,那么请立即提供
  • Depending on the number of processors on the system you are running this application you can set the flag for -XX:ParallelGCThreads=## .根据您运行此应用程序的系统上的处理器数量,您可以为-XX:ParallelGCThreads=##设置标志。
  • I havent tried this one but the documentation shows a parameter for -XX:+UseParallelOldGC which shows some promise to reduce time of old GC collection.我还没有尝试过这个,但文档显示了-XX:+UseParallelOldGC一个参数,它显示了一些减少旧 GC 收集时间的承诺。
  • Try changing your new generation size to 1/4 of the Heap.尝试将新一代大小更改为堆的 1/4。 (1024 instead of 64) This could be forcing too much to the old generation. (1024 而不是 64)这可能对老年代的影响太大。 The default size is around 30%, you have your application configured to use around 2% for young gen.默认大小约为 30%,您将应用程序配置为使用约 2% 的年轻代。 Though you have no max size configured, I worry that too much data would be moved to old gen because the new gen is too small to handle all of the requests.虽然您没有配置最大大小,但我担心太多数据会被移动到旧代,因为新代太小而无法处理所有请求。 Thus you have to perform more full (paused) GC's in order to clean up the memory.因此,您必须执行更多完整(暂停)的 GC 以清理内存。

I do believe overall if you are allocating this much memory so fast, then it could be a generation problem where the memory is allocated to the Old generation prematurely.我相信总的来说,如果你如此快地分配这么多内存,那么它可能是一个代问题,内存过早分配给老年代。 If a tweak to your new gen size doesn't work, then you need to either add more heap via the -Xmx configuration, or take a step back and find exactly what is holding onto the memory.如果对新的 gen 大小的调整不起作用,那么您需要通过 -Xmx 配置添加更多堆,或者退后一步并准确找出占用内存的内容。 The MAT tool which we discussed earlier can show you the references holding onto the objects in memory.我们之前讨论过的 MAT 工具可以向您展示保留在内存中的对象的引用。 I would recommend trying bullet points 1 & 4 first.我建议先尝试第 1 点和第 4 点。 This will be trial and error for you to get the right values这将是反复试验以获得正确的值

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM