java JVM 消耗 100% CPU,大量 GC
声明:本页面是StackOverFlow热门问题的中英对照翻译,遵循CC BY-SA 4.0协议,如果您需要使用它,必须同样遵循CC BY-SA许可,注明原文地址和作者信息,同时你必须将它归于原作者(不是我):StackOverFlow
原文地址: http://stackoverflow.com/questions/27003451/
Warning: these are provided under cc-by-sa 4.0 license. You are free to use/share it, But you must attribute it to the original authors (not me):
StackOverFlow
JVM consumes 100% CPU with a lot of GC
提问by Matthias M
After running a few days the CPU load of my JVM is about 100% with about 10% of GC (screenshot).
运行几天后,我的 JVM 的 CPU 负载约为 100%,GC 约为 10%(截图)。
The memory consumption is near to max (about 6 GB). The tomcat is extremely slow at that state.
内存消耗接近最大值(约 6 GB)。在那个状态下,tomcat 非常慢。
采纳答案by Matthias M
I learned to check this on GC problems:
我学会了检查 GC 问题:
- Give the JVM enough memory e.g.
-Xmx2G
- If memory is not sufficient and no more RAM is available on the host, analyze the HEAP dump (e.g. by jvisualvm).
- Turn on Concurrent Marc and Sweep:
-XX:+UseConcMarkSweepGC -XX:+UseParNewGC
- Check the garbage collection log:
-verbose:gc -XX:+PrintGCDetails -XX:+PrintGCTimeStamps -Xloggc:gc.log
- 给JVM足够的内存,例如
-Xmx2G
- 如果内存不足且主机上没有更多可用 RAM,请分析 HEAP 转储(例如通过 jvisualvm)。
- 打开并发 Marc 和 Sweep:
-XX:+UseConcMarkSweepGC -XX:+UseParNewGC
- 检查垃圾收集日志:
-verbose:gc -XX:+PrintGCDetails -XX:+PrintGCTimeStamps -Xloggc:gc.log
My Solution:
我的解决方案:
But I solved that problem finally by tuning the cache sizes. The cache sizes were to big, so memory got scarce.
但我最终通过调整缓存大小解决了这个问题。缓存大小太大,因此内存不足。
回答by the8472
Since it's too much for a comment i'll write it up ans answer:
由于评论太多,我将其写下来并回答:
Looking at your charts it seems to be using CPU for non-GC tasks, peak "GC activity" seems to stay within 10%.
查看您的图表,似乎将 CPU 用于非 GC 任务,峰值“GC 活动”似乎保持在 10% 以内。
So on first impression it would seem that your task is simply CPU-bound, so if that's unexpected maybe you should do some CPU-profiling on your java application to see if something pops out.
因此,在第一印象中,您的任务似乎只是受 CPU 限制,因此如果出乎意料,您可能应该对 Java 应用程序进行一些 CPU 分析,以查看是否会弹出某些内容。
Apart from that, based on comments I suspect that physical memory filling up might evict file caches and memory-mapped things, leading to increased page faults which forces the CPU to wait for IO.
除此之外,根据评论,我怀疑物理内存填满可能会驱逐文件缓存和内存映射的东西,导致页面错误增加,迫使 CPU 等待 IO。
Freeing up 500MB on a manual GC out of a 4GB heap does not seem all that much, most GCs try to keep pause times low as their primary goal, keep the total time spent in GC within some bound as secondary goal and only when the other goals are met they try to reduce memory footprint as tertiary goal.
在手动 GC 上从 4GB 堆中释放 500MB 似乎并不多,大多数 GC 尝试将暂停时间保持在较低的水平作为其主要目标,将在 GC 中花费的总时间保持在某个范围内作为次要目标,并且仅当另一个目标达到目标,他们尝试减少内存占用作为第三个目标。
Before recommending further steps you should gather more statistics/provide more information since it's hard to even discern what your actual problem is from your description.
在推荐进一步的步骤之前,您应该收集更多统计信息/提供更多信息,因为甚至很难从您的描述中辨别出您的实际问题是什么。
- monitor page faults
- figure out which GC algorithm is used in your setup and how they're tuned (-XX:+PrintFlagsFinal)
- log GC activity - I suspect it's pretty busy with minor GCs and thus eating up its pause time or CPU load goals
- perform allocation profiling of your application (anything creating excessive garbage?)
- 监控页面错误
- 弄清楚您的设置中使用了哪种 GC 算法以及它们是如何调整的 (-XX:+PrintFlagsFinal)
- 记录 GC 活动 - 我怀疑它非常忙于小 GC,因此耗尽了它的暂停时间或 CPU 负载目标
- 执行应用程序的分配分析(任何会产生过多垃圾的东西?)
You also have to be careful to distinguish problems caused by the java heap reaching its sizing limit vs. problems causing by the OS exhausting its physical memory.
您还必须小心区分由 Java 堆达到其大小限制引起的问题与由操作系统耗尽其物理内存引起的问题。
TL;DR: Unclear problem, more information required.
TL;DR:问题不明确,需要更多信息。
Or if you're lazy/can afford it just plug in more RAM / remove other services from the machine and see if the problem goes away.
或者,如果您很懒惰/负担得起,只需插入更多 RAM/从机器中删除其他服务,看看问题是否消失。
回答by Denis Lukenich
if you want keep the memory of your server free you can simply try the vm-parameter
如果您想保持服务器的内存空闲,您可以简单地尝试使用 vm-parameter
-Xmx2G //or any different value
This ensures your program never takes more than 2 Gigabyte of Ram. But be aware if case of high workload the server may be get an OutOfMemoryError.
这可确保您的程序永远不会占用超过 2 GB 的内存。但请注意,如果工作负载高,服务器可能会出现 OutOfMemoryError。
Since a old generation (full) GC may block your whole server from working for some seconds java will try to avoid a Full Garbage collection.
由于老一代(完整)GC 可能会阻止您的整个服务器工作几秒钟,java 将尝试避免完整垃圾收集。
The Ram-Limitation may trigger a Full-Generation GC more easy (or even support more objects to be collected by Young-Generation GC).
Ram-Limitation 可能更容易触发 Full-Generation GC(甚至支持 Young-Generation GC 收集更多对象)。
From my (more guessing than actually knowing) opinion: I don't think another algorithm can help so much here.
根据我的(猜测多于实际了解)意见:我认为其他算法在这里没有多大帮助。