当前位置: 首页 > 知识库问答 >
问题:

为什么java堆分配大小调整会导致OOME?

宋昕
2023-03-14

我们在html" target="_blank">日志中看到了OutOfMemoryExceptions,它们似乎与java堆提交大小从~1G增长到~2.4G一致。尽管有错误消息,但堆空间似乎没有用完。除了抛出异常(和生成的堆转储)之外,调整大小似乎最终会成功,应用程序继续运行,没有任何问题(堆提交大小约2.4G)。

下面是日志输出的一个示例:

INFO   | jvm 1    | 2013/08/16 12:08:05 | [GC [PSYoungGen: 328000K->2997K(339200K)] 645686K->320683K(1038272K), 0.0101580 secs] [Times: user=0.01 sys=0.00, real=0.00 secs] 
INFO   | jvm 1    | 2013/08/16 12:09:14 | [GC [PSYoungGen: 331509K->3487K(338816K)] 649195K->322153K(1037888K), 0.0115600 secs] [Times: user=0.02 sys=0.00, real=0.01 secs] 
INFO   | jvm 1    | 2013/08/16 12:09:59 | [GC [PSYoungGen: 331999K->2928K(340032K)] 650665K->322608K(1039104K), 0.0099300 secs] [Times: user=0.02 sys=0.00, real=0.01 secs] 
INFO   | jvm 1    | 2013/08/16 12:10:48 | [GC [PSYoungGen: 333104K->2723K(339648K)] 652784K->323240K(1038720K), 0.0100130 secs] [Times: user=0.02 sys=0.00, real=0.01 secs] 
INFO   | jvm 1    | 2013/08/16 12:11:28 | [GC [PSYoungGen: 332885K->3884K(340864K)] 653402K->325089K(1039936K), 0.0106250 secs] [Times: user=0.02 sys=0.00, real=0.01 secs] 
INFO   | jvm 1    | 2013/08/16 12:11:39 | [GC [PSYoungGen: 23694K->463K(340352K)] 344899K->323656K(2437504K), 0.0070330 secs] [Times: user=0.01 sys=0.00, real=0.00 secs] 
INFO   | jvm 1    | 2013/08/16 12:11:39 | [GC [PSYoungGen: 463K->0K(340608K)] 323656K->323592K(2437760K), 0.0044440 secs] [Times: user=0.02 sys=0.00, real=0.01 secs] 
INFO   | jvm 1    | 2013/08/16 12:11:39 | [Full GC
INFO   | jvm 1    | 2013/08/16 12:11:40 |  [PSYoungGen: 0K->0K(340608K)] [PSOldGen: 323592K->323592K(699072K)] 323592K->323592K(1039680K) [PSPermGen: 159297K->159297K(262144K)], 1.2076900 secs] [Times: user=1.20 sys=0.00, real=1.21 secs] 
INFO   | jvm 1    | 2013/08/16 12:11:40 | [GC [PSYoungGen: 0K->0K(340736K)] 323592K->323592K(2437888K), 0.0046330 secs] [Times: user=0.02 sys=0.00, real=0.00 secs] 
INFO   | jvm 1    | 2013/08/16 12:11:40 | [Full GC
INFO   | jvm 1    | 2013/08/16 12:11:42 |  [PSYoungGen: 0K->0K(340736K)] [PSOldGen: 323592K->279953K(744512K)] 323592K->279953K(1085248K) [PSPermGen: 159297K->159062K(262144K)], 1.7593100 secs] [Times: user=1.75 sys=0.00, real=1.76 secs] 
INFO   | jvm 1    | 2013/08/16 12:11:42 | java.lang.OutOfMemoryError: Java heap space
INFO   | jvm 1    | 2013/08/16 12:11:42 | Dumping heap to java_pid28908.hprof ...
INFO   | jvm 1    | 2013/08/16 12:11:48 | Heap dump file created [463314899 bytes in 6.037 secs]
INFO   | jvm 1    | 2013/08/16 12:12:36 | [GC [PSYoungGen: 331840K->6044K(352192K)] 611793K->285998K(2449344K), 0.0164060 secs] [Times: user=0.02 sys=0.00, real=0.02 secs] 
INFO   | jvm 1    | 2013/08/16 12:13:28 | [GC [PSYoungGen: 352156K->6161K(364160K)] 632110K->286114K(2461312K), 0.0152330 secs] [Times: user=0.02 sys=0.01, real=0.01 secs] 
INFO   | jvm 1    | 2013/08/16 12:14:47 | [GC [PSYoungGen: 364113K->6575K(374144K)] 644066K->288169K(2471296K), 0.0179930 secs] [Times: user=0.02 sys=0.01, real=0.02 secs] 

请注意,在OOME之前,提交的堆总数在1GB和2.4GB之间振荡。我们可以看到,它之前非常稳定在1GB,之后非常稳定在2.4GB。

    null

更新:我们试图通过将初始内存(Xms)设置为最大内存(Xmx)来防止这种情况。到目前为止,这些实验一直很有希望,尽管我们还没有引入生产的变化。它仍然没有解释为什么首先会出现OOME,尽管它似乎表明在不增加最大堆大小(或减少应用程序内存占用)的情况下可以避免OOME。因此,为什么堆大小调整会导致OOME仍然是一个谜?

共有1个答案

樊腾
2023-03-14

对于阅读日志来说,你似乎有一个非常大的活动爆发,最像是大到足以直接进入终身/老一代的对象。我仍然建议您增加最大内存,以查看应用程序的行为,因为OOME可能会给您带来令人困惑的统计数据。

这意味着大量的早期提升。“GC”是一个小集合,它看起来每个对象都是需要的,触发一个完整的GC,它找到一些可以删除的终身对象。当年轻的对象死在伊甸园空间时,GC工作得最好,但似乎你的大多数对象死在终身空间。

测试这一点的一种方法是使最大堆空间大得多。如果您可以尝试一个24 GB的堆或80%的主内存,看看它的行为。例如,如果您有32 GB内存,请尝试-xmx24g。从这些数字来看,似乎你想要一个至少5 GB的伊甸园大小。

 类似资料:
  • 问题内容: 在放入HashMap期间发生冲突时,是否会调整地图大小或将条目添加到该特定存储桶中的列表中? 问题答案: 当您说“冲突”时,您是指相同的哈希码吗?哈希码用于确定要使用HashMap中的哪个存储桶,并且该存储桶由具有相同哈希码的所有条目的链表组成。然后在返回或引导(获取/放入)之前比较条目的相等性(使用.equals())。 请注意,这是专门用于HashMap的(因为这是您所要求的),而

  • 我们将和设置为1536m。现在,如果我理解正确的话,j-xmx表示堆的最大大小。 本系统采用4核15GB ram进程。 但是,当我检查正在运行的Java进程的RSS(使用top)时,我看到它使用的值比大,大约。 对于来说,有4个内核和15GB RAM的理想设置是什么(假设除了Java应用程序之外,系统中没有其他进程在运行)

  • 所以问题是在主题中。我认为我没有正确理解重新分区的工作。在我的脑海中,当我说时,我希望所有数据都将在工作人员(假设60个工作人员)之间按相等的大小进行分区。 举个例子。我会在不平衡的文件中加载大量数据,比如400个文件,其中20%的文件大小为2Gb,其他80%的文件大小约为1Mb。我有加载此数据的代码: 然后,我希望将原始数据转换为中间对象,过滤不相关的记录,转换为最终对象(带有附加属性),然后按

  • 问题内容: 此代码 运行约30秒后给出此错误消息 而这段代码 几乎可以立即完美运行,并产生10MB的文件。据我了解,流的要点是两个版本应该在大约相同的时间内运行,因为数据是相同的。即使每次迭代将s 的数量增加到100或1000,也几乎不会增加运行时间,并且写入1GB文件没有任何问题。在1e6次迭代中每次迭代编写一个字符也可以正常工作。 这里发生了什么? 问题答案: 发生内存不足错误是因为您没有等待

  • 如果我逃跑 在铬33上,我得到 为什么?

  • 问题内容: 在添加新的键值对时,我有几个关于重建的问题。我将基于以下事实提出问题(对于Oracle JVM来说是正确的,不确定它们是否对其他JVM正确): 每当您将HashMap增大到大于阈值(阈值= loadFactor * numberOfEntries)时,调整大小即可重新构建以具有更大的内部表数组。新创建的Entry放在哪个存储区中无关紧要-地图仍会变大。即使所有条目都进入一个存储桶(即,