Java G1 GC占用太多内存

5
例如,我将-Xmx设置为40G。我期望我的Java处理器不使用超过40G的内存。
我的程序在使用cms-gc时运行良好。
但是当我改用相同内存量的G1 gc时(即使增加了15%的内存),它总是被oom killer杀掉。
我发现了一些类似于这样的文章:为什么我的Java进程消耗的内存超过Xmx? 它表达了以下内容:
 G1 is especially known for its 
 excessive appetite for additional memory, so be aware of this.

我想知道如何限制g1 gc使用的内存以及为什么g1需要使用更多的附加内存。

2个回答

2

你提到的文章(为什么我的Java进程消耗的内存比Xmx还多?)已经清楚地概述了这个问题。

Java进程需要内存来完成以下几件事情:

  • Java堆(也称为内存分配池)
  • 应用程序中每个线程的堆栈
  • JVM本身使用的内存(也称为permgen)
  • 由本机函数(JRE或第三方库)分配的内存

另一个问题是,一些JVM内存不被视为permgen内存,无法控制。

因此,如果您想将Java应用程序限制在40 GB,则必须考虑所有类型的内存。从较小的值开始,例如:

-Xmx30g -XX:MaxPermSize=1g -Xss1m

然后观察您的进程的内存使用情况,如果进程安全地远离目标40GB,请增加Xmx


实际上,我已经按照您指定的所有参数为我的程序进行了特定设置。但是仍然被OOM Killer杀死。但是当我使用CMS GC时,它可以正常工作(但速度较慢)。所以我想知道原因。 - yunfan
所以我只想知道是否可以限制G1垃圾回收的内存。 - yunfan
1
什么是“gc内存”? - Codo
2
Java 8或更新版本中没有Permgen,因此对于这些版本指定“-XX:MaxPermSize = 1g”将无效。 - Holger
据我所知,没有参数可以控制GC1开销。Java也没有其他许多内存分配的参数。但很可能GC1开销与池分配内存有关。简而言之:您必须调整Xmx参数,直到整个进程内存适合您可用的内存。由于没有直接限制整个进程内存的参数,因此这将是试错过程。 - Codo
显示剩余2条评论

0

你不能限制G1需要使用的东西。如果你能这样做 - 你会破坏一切或因为堆内存错误而死亡,因为G1将没有资源来正常运行。要解释为什么这个算法需要使用额外的内存并不简单。它至少需要用于card tableremembered sets的空间,这就是为什么。它需要内存来存储SATB队列,这些是在GC周期处于活动状态时“拦截”堆写入和读取的一些数据结构。我敢打赌还有更多的内存要求。总的来说,如果你想要并发性(让你的应用在GC周期处于活动状态时运行),你需要提供更多的内存。


网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接