Java 6 Update 25 VM崩溃:内存不足

时间:2011-06-14 13:49:57

标签: java windows eclipse crash jvm

有关此问题的更新 - 请参阅下文。

我遇到了(可重现的,至少对我而言)jvm 崩溃不是OutOfMemoryError ) (崩溃的应用程序是eclipse 3.6.2)。 但是,查看崩溃日志让我感到疑惑:

#
# There is insufficient memory for the Java Runtime Environment to continue.
# Native memory allocation (malloc) failed to allocate 65544 bytes for Chunk::new
# Possible reasons:
#   The system is out of physical RAM or swap space
#   In 32 bit mode, the process size limit was hit
# Possible solutions:
#   Reduce memory load on the system
#   Increase physical memory or swap space
#   Check if swap backing store is full
#   Use 64 bit Java on a 64 bit OS
#   Decrease Java heap size (-Xmx/-Xms)
#   Decrease number of Java threads
#   Decrease Java thread stack sizes (-Xss)
#   Set larger code cache with -XX:ReservedCodeCacheSize=
# This output file may be truncated or incomplete.

Current thread (0x531d6000):  JavaThread "C2 CompilerThread1" daemon 
[_thread_in_native, id=7812, stack(0x53af0000,0x53bf0000)]

Stack: [0x53af0000,0x53bf0000],  sp=0x53bee860,  free space=1018k
Native frames: (J=compiled Java code, j=interpreted, Vv=VM code, C=native code)
V  [jvm.dll+0x1484aa]
V  [jvm.dll+0x1434fc]
V  [jvm.dll+0x5e6fc]
V  [jvm.dll+0x5e993]
V  [jvm.dll+0x27a571]
V  [jvm.dll+0x258672]
V  [jvm.dll+0x25ed93]
V  [jvm.dll+0x260072]
V  [jvm.dll+0x24e59a]
V  [jvm.dll+0x47edd]
V  [jvm.dll+0x48a6f]
V  [jvm.dll+0x12dcd4]
V  [jvm.dll+0x155a0c]
C  [MSVCR71.dll+0xb381]
C  [kernel32.dll+0xb729]

我正在使用Windows XP 32位SP3。我有4GB内存。 在启动应用程序之前,我根据任务管理器释放了2 GB空闲(+ 1 GB系统缓存也可以释放)。我肯定有足够的免费RAM。

从开始到崩溃我使用visualvm和jconsole记录了jvm内存统计信息。 我获取了内存消耗统计信息,直到崩溃前的最后时刻。

统计信息显示以下分配的内存大小:

  • HeapSize: 751 MB(使用248 MB)
  • 非HeapSize(PermGen& CodeCache): 150 MB(使用95 MB)
  • 内存管理区域的大小(Edenspace,Old-gen等): 350 MB
  • 线程堆栈大小: 17 MB (根据oracle并且由于51个线程正在运行)

我正在使用参数运行应用程序(jre 6 update 25,server vm):

-XX:PermSize=128m
-XX:MaxPermSize=192m
-XX:ReservedCodeCacheSize=96m
-Xms500m
-Xmx1124m

问题:

  • 当vm和操作系统上有足够的内存时,为什么jvm会崩溃?
    通过上述设置,我认为我无法达到2GB 32位限制(1124MB + 192MB + 96MB +线程堆栈<2GB)。在任何其他情况下(堆分配太多),我宁愿期待OutOfMemoryError而不是jvm崩溃

谁能帮助我弄清楚这里出了什么问题?

(注意:我最近从Eclipse 3.4.2升级到Eclipse 3.6.2,从Java 5升级到Java 6.我怀疑崩溃和这些更改之间存在连接,因为我之前没有看到过这些)< / p>

更新

Java 6 Update 25 中引入了

It seems to be a jvm bug ,并且与新的jit编译器有关。另见this blog entry. 根据博客,这个bug的修复应该是下一个java 6更新的一部分。 与此同时,我在崩溃期间获得了本机堆栈跟踪。我已经更新了上面的崩溃日志。

建议的解决方法,使用vm参数-XX:-DoEscapeAnalysis有效(至少可以显着降低崩溃的可能性)

4 个答案:

答案 0 :(得分:1)

我在工作中偶然发现了类似的问题。我们为我们的应用程序设置了-Xmx65536M,但仍然得到了完全相同的错误。有趣的是,错误总是发生在我们的应用程序实际上正在做相当轻量级的计算时,相对来说,并且因此远远没有达到这个限制。

我们在网上找到了解决问题的可能方案:http://www.blogsoncloud.com/jsp/techSols/java-lang-OutOfMemoryError-unable-to-create-new-native-thread.jsp,它似乎解决了我们的问题。将-Xmx降低到50G后,我们没有遇到这些问题。

案件中实际发生的事情对我们来说仍然有些不清楚。

答案 1 :(得分:1)

Windows的32位JVM上的

2GB不正确。 https://blogs.sap.com/2019/10/07/does-32-bit-or-64-bit-jvm-matter-anymore/

由于您使用的是Windows XP,因此您只能使用32位JVM。

在Windows上的32位VM上,最大堆为1.5GB。您现在只有1412MB,没有线程。您是否尝试减小交换堆栈大小-Xss,并尝试消除最初分配的PermSize:-XX:PermSize = 128m?听起来这是个月食问题,而不是一个内存问题。

可以迁移到另一台机器上的较新的JVM或其他(64位)JVM吗?即使您的目标是Windows-XP,也没有理由在其上进行 develop 的开发,除非您必须这样做。 Eclipse可以轻松地在远程机器上运行,调试和部署代码。

Eclipse的JVM可能不同于您在Eclipse或Eclipse中运行的事物的JVM。 Eclipse是记忆中的猪。您可以消除不必要的eclipse插件以使用更少的eclipse内存,它附带了您可能不需要或不需要的东西。

尝试使引用无效(以消除循环上无法收集的GC对象),重新使用分配的内存,使用单例,并分析内存使用情况以消除不必要的对象,引用和分配。其他提示:

  • 首选静态内存分配,即每个VM分配一次 动态。
  • 避免在函数内创建临时对象-考虑使用reset()方法,该方法可以允许对象重复使用
  • 避免String突变和自动装箱类型的突变。

答案 2 :(得分:0)

我认为@ ggb667已将其与JVM崩溃的原因联系在一起。 32位Windows体系结构限制将Java应用程序的可用RAM限制为1.5GB 1 ...而不是您推测的2GB。另外,您还忽略了包含可执行文件,共享库,本机堆和“其他内容”的代码段所占用的地址空间。

基本上,这不是JVM错误。您只是在不受硬件和操作系统限制的情况下运行。

某些版本的Windows中有PAE (Physical Address Extension)支持形式的可能解决方案。根据链接,带有PAE的Windows XP为用户进程提供了多达4GB的可用地址空间。但是,有关设备驱动程序支持的注意事项。

另一种可能的解决方案是减小最大堆大小,并执行其他操作以减少应用程序的内存使用率。例如在Eclipse中减少工作空间中“打开”项目的数量。

另请参阅:Java maximum memory on Windows XP

1-不同的消息来源对实际限制有不同的说法,但实际上少于2GB。坦率地说,实际限制是多少都没有关系。


在理想世界中,任何人都不应再对这个问题产生实际兴趣。 2020年:

  • 您不应该运行Windows XP。自2014年4月起已经停产
  • 您不应该运行Java6。自2013年4月起生命已经终止
  • 如果您仍在运行Java 6,则应使用最新的公共修补程序版本:1.6.0_45。 (或者,如果您已经拥有支持合同,则在更高版本的1.6非公开发行中使用。)

无论哪种方式,都不应在此系统上运行Eclipse。认真地说,您可以花几百美元买一台新的64位计算机,并增加内存,以此类推,这将使您能够运行最新的操作系统和最新的Java版本。您应该使用 that 来运行Eclipse。

如果您确实需要在具有旧版Java的旧32位计算机上进行Java开发(因为您负担不起更新的计算机),建议您使用简单的文本编辑器和Java 6 JDK命令行工具(以及Ant,Maven和Gradle等第三方Java构建工具)。

最后,如果您仍在尝试运行/维护卡在Java 6上的Java软件,那么您确实应该尝试摆脱这一漏洞。生活只会让你更艰难:

  • 如果Java 6软件是内部开发的,或者您具有源代码,则将其移植。
  • 如果您依赖Java 6上的专有软件,请寻找新的供应商。
  • 如果管理层拒绝,请告诉他们,他们可能需要“关闭”。

您/您的组织应该在七年前处理此问题。

答案 3 :(得分:-2)

JVM有自己的限制,在达到物理或虚拟内存限制之前很久就会停止它。您需要调整的是堆大小,它与另一个-X标志一起使用。 (我认为它有点像-XHeapSizeLimit这样的创意,但我会在一秒钟内查看。)

Here we go

  

-Xmsn指定内存分配池的初始大小(以字节为单位)。   该值必须是1024的倍数   大于1MB。附上字母k   或K表示千字节,或m或M.   表示兆字节。默认   值是2MB。例子:

   -Xms6291456
   -Xms6144k
   -Xms6m
     

-Xmxn指定内存分配池的最大大小(以字节为单位)。   该值必须是1024的倍数   大于2MB。附上字母k   或K表示千字节,或m或M.   表示兆字节。默认   值是64MB。例子:

   -Xmx83886080
   -Xmx81920k
   -Xmx80m