首页
学习
活动
专区
圈层
工具
发布
社区首页 >问答首页 >100%已满的Eden空间,0%已使用的Survivor空间-未完成垃圾收集

100%已满的Eden空间,0%已使用的Survivor空间-未完成垃圾收集
EN

Stack Overflow用户
提问于 2012-07-05 15:29:46
回答 3查看 47.8K关注 0票数 26

我遇到了一个相当令人困惑的GC案例:当Eden空间100%已满时,survivor空间却被使用了0%。当伊甸园已满时,应该触发垃圾收集,对吧?

会有GC守护进程被阻止运行的情况吗?比如100%的CPU?

我们使用的是jdk-1.7

可能的原因是什么?下面是jmap输出。

我们还尝试使用jmap -histo -F捕获更详细的内存使用情况,但随后CPU使用率下降到0%,java进程变得不可访问。

代码语言:javascript
复制
using thread-local object allocation.
Parallel GC with 18 thread(s)

Heap Configuration:
   MinHeapFreeRatio = 40
   MaxHeapFreeRatio = 70
   MaxHeapSize      = 12884901888 (12288.0MB)
   NewSize          = 1310720 (1.25MB)
   MaxNewSize       = 17592186044415 MB
   OldSize          = 5439488 (5.1875MB)
   NewRatio         = 2
   SurvivorRatio    = 8
   PermSize         = 21757952 (20.75MB)
   MaxPermSize      = 85983232 (82.0MB)
   G1HeapRegionSize = 0 (0.0MB)

Heap Usage:
PS Young Generation
Eden Space:
   capacity = 4265738240 (4068.125MB)
   used     = 4265738240 (4068.125MB)
   free     = 0 (0.0MB)
   100.0% used
From Space:
   capacity = 14352384 (13.6875MB)
   used     = 0 (0.0MB)
   free     = 14352384 (13.6875MB)
   0.0% used
To Space:
   capacity = 14680064 (14.0MB)
   used     = 0 (0.0MB)
   free     = 14680064 (14.0MB)
   0.0% used
PS Old Generation
   capacity = 8589934592 (8192.0MB)
   used     = 8589931920 (8191.997451782227MB)
   free     = 2672 (0.0025482177734375MB)
   99.99996889382601% used
PS Perm Generation
   capacity = 41353216 (39.4375MB)
   used     = 41079056 (39.17604064941406MB)
   free     = 274160 (0.2614593505859375MB)
   99.33702858805468% used
EN

回答 3

Stack Overflow用户

发布于 2012-07-05 16:05:19

当我看到您的堆配置时,我发现

MaxNewSize = 17592186044415 MB不正确,但它必须以字节为单位。

我所看到的是,几乎所有的几代都是满的,并且Collector正在尝试收集这两代人,所以他们相互阻塞。

我建议使用下面的参数来调整内存。

代码语言:javascript
复制
-XX:NewRatio=3 - the young generation will occupy 1/4 the overall heap
-XX:NewSize - Calculated automatically if you specify -XX:NewRatio
-XX:MaxNewSize - The largest size the young generation can grow to (unlimited if this value is not specified at command line)

我还建议使用一些幸存空间,当对象从eden复制到“永久”生成时,它将为时间收集器提供时间收集。

代码语言:javascript
复制
-XX:SurvivorRatio=6 - each survivor space will be 1/8 the young generation

如果存活者空间太小,则复制集合溢出会直接进入租期生成。

有关任何说明,请参阅this链接。

编辑:

-XX:NewRatio=3 -年轻一代将占据整个堆的1/4

计算:

代码语言:javascript
复制
    y/t=1/3

    y+t=h
    y+3y=h
    y=h/4

 t=tenured
 y=young
 h=heap
票数 11
EN

Stack Overflow用户

发布于 2012-07-05 16:11:24

线程本地缓冲区是从eden空间分配的。一旦分配了缓冲区,eden空间中的空闲空间就会完全减少。这可能意味着您有许多几乎为空的TLAB,但eden空间似乎已满。当eden空间中没有足够的空闲空间时,会触发GC。

如果您关闭TLAB -XX:-UseTLAB,这将降低性能,但您将获得有关空间使用情况的更准确的计算。

票数 6
EN

Stack Overflow用户

发布于 2012-07-05 15:54:29

这只是一个想法,但我看到老一代也是满员的。会不会是GC而不是试图清理伊甸园,而是忙于运行完整的GC,试图清理旧一代以避免OOM。

票数 2
EN
页面原文内容由Stack Overflow提供。腾讯云小微IT领域专用引擎提供翻译支持
原文链接:

https://stackoverflow.com/questions/11339679

复制
相关文章

相似问题

领券
问题归档专栏文章快讯文章归档关键词归档开发者手册归档开发者手册 Section 归档