简体   繁体   English

Java 6 更新 25 虚拟机崩溃:不足 memory

[英]Java 6 Update 25 VM crash: insufficient memory

For an update of this question - see below.有关此问题的更新 - 请参见下文。

I experience a (reproducible, at least for me) JVM crash ( not an OutOfMemoryError ) (The application which crashes is eclipse 3.6.2).我遇到了(至少对我来说是可重现的)JVM崩溃不是 OutOfMemoryError )(崩溃的应用程序是 eclipse 3.6.2)。 However, looking at the crash log makes me wonder:但是,查看崩溃日志让我想知道:

#
# 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]

I am using Windows XP 32-bit SP3.我正在使用 Windows XP 32 位 SP3。 I have 4GB RAM.我有 4GB 内存。 Before starting the application I had 2 GB free according to the task manager (+ 1 GB system cache which might be freed as well.).根据任务管理器,在启动应用程序之前,我有 2 GB 可用空间(+ 1 GB 系统缓存也可能被释放。)。 I am definitely having enough free RAM.我肯定有足够的空闲 RAM。

From the start till the crash I logged the JVM memory statistics using visualvm and jconsole.从开始到崩溃,我使用 visualvm 和 jconsole 记录了 JVM memory 统计信息。 I acquired the memory consumption statistics until the last moments before the crash.我获取了 memory 消耗统计数据,直到崩溃前的最后一刻。

The statistics shows the following allocated memory sizes:统计显示以下分配的 memory 大小:

  • HeapSize: 751 MB (used 248 MB)堆大小: 751 MB(使用 248 MB)
  • Non-HeapSize(PermGen & CodeCache): 150 MB (used 95 MB)非堆大小(PermGen 和 CodeCache): 150 MB(使用 95 MB)
  • Size of memory management areas (Edenspace, Old-gen etc.): 350 MB memory 管理区域(Edenspace、Old-gen 等)的大小: 350 MB
  • Thread stack sizes: 17 MB (according to oracle and due the fact that 51 threads are running)线程堆栈大小: 17 MB (根据oracle并且由于 51 个线程正在运行)

I am running the application (jre 6 update 25, server vm) using the parameters:我正在使用以下参数运行应用程序(jre 6 update 25,服务器 vm):

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

Question:问题:

  • Why does the JVM crash when there's obviously enough memory on the VM and OS?当 VM 和 OS 上的 memory 明显足够时,为什么 JVM 会崩溃?
    With the above settings I think that I cannot hit the 2GB 32-bit limit (1124MB+192MB+96MB+thread stacks < 2GB).通过上述设置,我认为我无法达到 2GB 32 位限制(1124MB+192MB+96MB+线程堆栈 < 2GB)。 In any other case (too much heap allocation), I would rather expect an OutOfMemoryError than a JVM crash在任何其他情况下(堆分配过多),我宁愿期待 OutOfMemoryError 而不是 JVM 崩溃

Who can help me to figure out what is going wrong here?谁能帮我弄清楚这里出了什么问题?

(Note: I upgraded recently to Eclipse 3.6.2 from Eclipse 3.4.2 and from Java 5 to Java 6. I suspect that there's a connection between the crashes and these changes because I haven't seen these before) (Note: I upgraded recently to Eclipse 3.6.2 from Eclipse 3.4.2 and from Java 5 to Java 6. I suspect that there's a connection between the crashes and these changes because I haven't seen these before)

UPDATE更新

It seems to be a JVM bug introduced in Java 6 Update 25 and has something to do with the new jit compiler. 这似乎是Java 6 Update 25中引入的 JVM 错误,与新的 jit 编译器有关。 See also this blog entry.另请参阅此博客条目。 According to the blog, the fix of this bug should be part of the next java 6 updates.根据博客,此错误的修复应该是下一个 java 6 更新的一部分。 In the meanwhile, I got a native stack trace during a crash.与此同时,我在崩溃期间获得了本机堆栈跟踪。 I've updated the above crash log.我已经更新了上面的崩溃日志。

The proposed workaround, using the VM argument -XX:-DoEscapeAnalysis works (at least it notably lowers the probability of a crash)建议的解决方法,使用 VM 参数-XX:-DoEscapeAnalysis有效(至少它显着降低了崩溃的可能性)

2GB on 32-bit JVM on Windows is incorrect. Windows 上的 32 位 JVM 上的 2GB 不正确。 https://blogs.sap.com/2019/10/07/does-32-bit-or-64-bit-jvm-matter-anymore/ https://blogs.sap.com/2019/10/07/does-32-bit-or-64-bit-jvm-matter-anymore/

Since you are on Windows-XP you are stuck with a 32 bit JVM.由于您使用的是 Windows-XP,因此您被 32 位 JVM 卡住了。

The max heap is 1.5GB on 32 bit VM on Windows. Windows 上的 32 位 VM 上的最大堆为 1.5GB。 You are at 1412MB to begin with without threads.开始时您的内存为 1412MB,没有线程。 Did you try decreasing the swap stack size -Xss, and have you tried eliminating the PermSize allocated initially: -XX:PermSize=128m?您是否尝试减小交换堆栈大小 -Xss,是否尝试消除最初分配的 PermSize:-XX:PermSize=128m? Sounds like this is an eclipse problem, not a memory-problem per-se.听起来这是一个 eclipse 问题,而不是内存问题本身。

Can you move to a newer JVM or different (64-bit) JVM on a different machine?您可以在不同的机器上移动到更新的 JVM 或不同的(64 位)JVM 吗? Even if you are targeting windows-XP there is no reason to develop on it, unless you HAVE to.即使您的目标是 windows-XP,也没有理由在其上进行开发,除非您必须这样做。 Eclipse can run, debug and deploy code on remote machines easily. Eclipse 可以轻松地在远程机器上运行、调试和部署代码。

Eclipse's JVM can be different then the JVM of things you run in or with eclipse. Eclipse 的 JVM 可能与您运行的 JVM 或 eclipse 不同。 Eclipse is a memory pig. Eclipse 是 memory 猪。 You can eliminate unnecessary eclipse plug-ins to use less eclipse memory, it comes with things out of the box you probably don't need or want.您可以消除不必要的 eclipse 插件以使用更少的 eclipse memory,它带有您可能不需要或不需要的开箱即用的东西。

Try to null out references (to eliminate circularly un-collectible GC objects), re-use allocated memory, use singletons, and profile your memory usage to eliminate unnecessary objects, references and allocations.尝试 null 出引用(以消除循环不可回收的 GC 对象),重新使用分配的 memory,使用单例,并分析您的 memory 使用以消除不必要的对象、引用和分配Additional tips:附加提示:

  • Prefer static memory allocation, ie allocate once per VM as opposed to dynamically.首选 static memory 分配,即每个 VM 分配一次,而不是动态分配。
  • Avoid creation of temporary objects within functions - consider a reset() method which can allow the object to reused避免在函数中创建临时对象 - 考虑使用可允许 object 重用的 reset() 方法
  • Avoid String mutations and mutation of auto boxed types.避免字符串突变和自动装箱类型的突变。

I think that @ggb667 has nailed it with the reason your JVM is crashing.我认为@ggb667 已经解决了您的 JVM 崩溃的原因。 32-bit Windows architectural constraints limit the available RAM for a Java application to 1.5GB 1 ... not 2GB as you surmised. 32 位 Windows 架构约束将 Java 应用程序的可用 RAM 限制为 1.5GB 1 ...而不是您推测的 2GB。 Also, you have neglected to include the address space occupied by the code segment of the executable, shared libraries, the native heap, and "other things".此外,您忽略了包括可执行文件的代码段、共享库、本机堆和“其他东西”占用的地址空间。

Basically, this is not a JVM bug.基本上,这不是 JVM 错误。 You are simply running against the limitations of your hardware and operating system.你只是在你的硬件和操作系统的限制下运行。

There is a possible solution in the form of PAE (Physical Address Extension ) support in some versions of Windows.在 Windows 的某些版本中存在一种可能的解决方案,即PAE(物理地址扩展)支持。 According to the link, Windows XP with PAE makes available up to 4GB of usable address spaces to user processes.根据该链接,带有 PAE 的 Windows XP 可为用户进程提供高达 4GB 的可用地址空间。 However, there are caveats about device driver support.但是,有关于设备驱动程序支持的警告。

Another possible solution is to reduce the max heap size, and do other things to reduce the application's memory utilization;另一种可能的解决方案是减少最大堆大小,并做其他事情来减少应用程序的 memory 利用率; eg in Eclipse reduce the number of "open" projects in your workspace.例如,在 Eclipse 中,减少工作区中“打开”项目的数量。

See also: Java maximum memory on Windows XP另请参阅: Java memory on Windows XP

1 - Different sources say different things about the actual limit, but it is significantly less than 2GB. 1 - 不同来源对实际限制的说法不同,但明显小于 2GB。 To be frank, it doesn't matter what the actual limit is.坦率地说,实际限制是多少并不重要。


In an ideal world this question should no longer be of practical interest to anyone.在一个理想的世界里,这个问题应该不再是任何人的实际兴趣。 In 2020: 2020年:

  • You shouldn't be running Windows XP.您不应该运行 Windows XP。 It has been end of life since April 2014自 2014 年 4 月起停产
  • You shouldn't be running Java 6. It has been end of life since April 2013您不应该运行 Java 6. 自 2013 年 4 月以来,它已停止使用
  • If you are still running Java 6, you should be at the last public patch release: 1.6.0_45.如果您仍在运行 Java 6,您应该处于最后一个公共补丁版本:1.6.0_45。 (Or a later 1.6 non-public release if you have / had a support contract.) (或者如果您有/曾经签订过支持合同,则可以在以后的 1.6 非公开版本中发布。)

Either way, you should not be running Eclipse on this system.无论哪种方式,您都不应该在此系统上运行 Eclipse。 Seriously, you can get a new 64-bit machine for a few hundred dollars with more memory, etc that will allow you to run an up-to-date operating system and an up-to-date Java release.说真的,你可以花几百美元买到一台新的 64 位机器,还有更多的 memory 等,这将使你能够运行最新的操作系统和最新的 Java 版本。 You should use that to run Eclipse.您应该使用来运行 Eclipse。

If you really need to do Java development on an old 32-bit machine with an old version of Java (because you can't afford a newer machine) you would be advised to use a simple text editor and the Java 6 JDK command line tools (and a 3rd-party Java build tool like Ant, Maven, Gradle). If you really need to do Java development on an old 32-bit machine with an old version of Java (because you can't afford a newer machine) you would be advised to use a simple text editor and the Java 6 JDK command line tools (以及第 3 方 Java 构建工具,如 Ant、Maven、Gradle)。

Finally, if you are still trying to run / maintain Java software that is stuck on Java 6, you should really be trying to get out of that hole.最后,如果您仍在尝试运行/维护卡在 Java 6 上的 Java 软件,那么您真的应该尝试摆脱这个漏洞。 Life is only going to get harder for you:对你来说,生活只会变得更加艰难:

  • If the Java 6 software was developed in-house or you have source code, port it.如果 Java 6 软件是内部开发的或者您有源代码,请移植它。
  • If you depend on proprietary software that is stuck on Java 6, look for a new vendor.如果您依赖于卡在 Java 6 上的专有软件,请寻找新的供应商。
  • If management says no, put it to them that they may need to "turn it off".如果管理层拒绝,告诉他们他们可能需要“关闭”。

You / your organization should have dealt with this issue this SEVEN years ago.您/您的组织应该在七年前就处理过这个问题。

I stumbled upon a similar problem at work.我在工作中偶然发现了一个类似的问题。 We had set -Xmx65536M for our application but kept getting exactly the same kind of errors.我们为我们的应用程序设置了 -Xmx65536M ,但一直收到完全相同类型的错误。 The funny thing is that the errors happened always at a time when our application was actually doing pretty lightweight calculations, relatively speaking, and was thus nowhere near this limit.有趣的是,错误总是发生在我们的应用程序实际上在进行相当轻量级的计算时,相对而言,因此离这个限制还很远。

We found a possible solution for the problem online: http://www.blogsoncloud.com/jsp/techSols/java-lang-OutOfMemoryError-unable-to-create-new-native-thread.jsp , and it seemed to solve our problem.我们在网上找到了一个可能的解决方案: http://www.blogsoncloud.com/jsp/techSols/java-lang-OutOfMemoryError-unable-to-create-new-native-thread.jsp ,它似乎解决了我们的问题问题。 After lowering -Xmx to 50G, we've had none of these issues.将 -Xmx 降低到 50G 后,我们没有遇到这些问题。

What actually happens in the case is still somewhat unclear to us.我们仍然不清楚案件中实际发生的情况。

The JVM has its own limits that will stop it long before it hits the physical or virtual memory limits. JVM 有自己的限制,在达到物理或虚拟 memory 限制之前很久就会停止。 What you need to adjust is the heap size, which is with another one of the -X flags.您需要调整的是堆大小,它与另一个 -X 标志一起使用。 (I think it's something creative like -XHeapSizeLimit but I'll check in a second.) (我认为这有点像 -XHeapSizeLimit 之类的创意,但我会检查一下。)

Here we go : 这里我们 go

-Xmsn Specify the initial size, in bytes, of the memory allocation pool. -Xmsn 指定 memory 分配池的初始大小,以字节为单位。 This value must be a multiple of 1024 greater than 1MB.此值必须是大于 1MB 的 1024 的倍数。 Append the letter k or K to indicate kilobytes, or m or M to indicate megabytes. Append 字母 k 或 K 表示千字节,或 m 或 M 表示兆字节。 The default value is 2MB.默认值为 2MB。 Examples:例子:

 -Xms6291456 -Xms6144k -Xms6m

-Xmxn Specify the maximum size, in bytes, of the memory allocation pool. -Xmxn 指定 memory 分配池的最大大小,以字节为单位。 This value must a multiple of 1024 greater than 2MB.此值必须是大于 2MB 的 1024 的倍数。 Append the letter k or K to indicate kilobytes, or m or M to indicate megabytes. Append 字母 k 或 K 表示千字节,或 m 或 M 表示兆字节。 The default value is 64MB.默认值为 64MB。 Examples:例子:

 -Xmx83886080 -Xmx81920k -Xmx80m

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM