PerfMa 給 OpenJDK 社群提交的第一個 Patch
概述
前兩天給openjdk gc-dev的email list提交了一個問題,主要是針對Full GC之後,GC日誌裡Metaspace的大小在GC前後都一直不變的問題,我在郵件裡大概也提了下如何修復該問題,以及猜測了下為什麼會有這個問題,內容比較簡單,就不翻譯啦,直接把郵件貼出來,PerfMa在後面會提交越來越多的patch給官方吧,雖然不一定每個patch都會被官方所接受,不過也希望為社群的發展貢獻一份我們的力量。
郵件內容
Hi, all
We use metaspace instead of perm since JDK8, I found that after the Full GC, the size of the metaspace has always been the same from the GC log. I have looked at the source code of hotspot roughly. It has not bean fixed in the latest version. The problem which may have some impact on us to troubleshoot some metaspace problems.
I wrote a test case, and simply analyzed the hotspot code, and showed the output before and after the modification. I hope this problem can be fixed as soon as possible.
Demo:
My demo is very simple, just constantly create a new class loader to load a specific class, after loading, execute a System GC, so that we can see the relevant GC log output, the JVM parameters we run are
The GC log is
Let’s look at the source code of hotspot,
GenCollectedHeap::do_collection:
We see that metaspace’s gc log output is executed before ClassLoaderDataGraph::purge();
, that means the size of the metaspace is printed without reclaiming the memory of the metaspace, so the GC log seems no change before and after the GC metaspace.
After knowing the specific problem, we can make an adjustment to the code to move the logic of the output of metaspace size after to ClassLoaderDataGraph::purge(),just like this:
At this point we recompile hotspot, execute the above demo again, you can see the correct output as follows
I also probably thought about why this problem is caused. This is the version before JDK8, such as JDK7, you can see the same code location:
It can be seen that the GC engineer at that time simply replaced print_perm_heap_change(perm_prev_used); with MetaspaceAux::print_metaspace_change(metadata_prev_used); but forgot the difference between Perm and Metaspace.
結語
大家也可以關注我們公司PerfMa的微信公眾號,後面會給大家帶來更多有意思有深度的技術文章。