“我该如何解决?”;sun.misc.Unsafe.allocateMemory(本机方法)处的java.lang.OutOfMemoryError“;?
我正在制作一个Java应用程序,它使用库来加载图像。但是,在某些计算机上,我在尝试运行程序时遇到以下错误:“我该如何解决?”;sun.misc.Unsafe.allocateMemory(本机方法)处的java.lang.OutOfMemoryError“;?,java,image,memory,graphics,Java,Image,Memory,Graphics,我正在制作一个Java应用程序,它使用库来加载图像。但是,在某些计算机上,我在尝试运行程序时遇到以下错误: Exception in thread "main" java.lang.OutOfMemoryError at sun.misc.Unsafe.allocateMemory(Native Method) at java.nio.DirectByteBuffer.<init>(DirectByteBuffer.java:99) at java.ni
Exception in thread "main" java.lang.OutOfMemoryError
at sun.misc.Unsafe.allocateMemory(Native Method)
at java.nio.DirectByteBuffer.<init>(DirectByteBuffer.java:99)
at java.nio.ByteBuffer.allocateDirect(ByteBuffer.java:288)
at org.lwjgl.BufferUtils.createByteBuffer(BufferUtils.java:60)
at org.newdawn.slick.opengl.PNGImageData.loadImage(PNGImageData.java:692)
at org.newdawn.slick.opengl.CompositeImageData.loadImage(CompositeImageData.java:62)
at org.newdawn.slick.opengl.CompositeImageData.loadImage(CompositeImageData.java:43)
线程“main”java.lang.OutOfMemoryError中出现异常
在sun.misc.Unsafe.allocateMemory(本机方法)
位于java.nio.DirectByteBuffer(DirectByteBuffer.java:99)
位于java.nio.ByteBuffer.allocateDirect(ByteBuffer.java:288)
位于org.lwjgl.BufferUtils.createByteBuffer(BufferUtils.java:60)
位于org.newdawn.slick.opengl.PNGImageData.loadImage(PNGImageData.java:692)
位于org.newdawn.slick.opengl.CompositeImageData.loadImage(CompositeImageData.java:62)
位于org.newdawn.slick.opengl.CompositeImageData.loadImage(CompositeImageData.java:43)
我的虚拟机选项包括:
-Djava.library.path=lib -Xms1024M -Xmx1024M -XX:PermSize=256M -XX:MaxPermSize=256M
-Djava.library.path=lib-Xms1024M-Xmx1024M-XX:PermSize=256M-XX:MaxPermSize=256M
程序在开始时加载一些大图像(1024x768分辨率)
如果您能帮助解决此问题,我们将不胜感激。这只是表明JVM内存不足。stacktrace的第一行在这里并不是真正相关的,因为它只是“碰巧”在JVM开始耗尽内存的地方,所有的垃圾收集都是徒劳的
基本上有两种解决方案:
字节[]
)第1点很容易做到,但如果代码中明显存在内存泄漏,则并不总是解决方案。第2点最好在a的帮助下确定下来。@BalusC在原因和解决方案方面基本上是正确的 然而,OOME的直接原因可能是在某些计算机上JVM无法将堆扩展到-XX选项指定的大小。例如,如果请求的内存量超过剩余的可用物理内存+交换空间,操作系统将拒绝JVM扩展堆的请求。这可能解释了为什么应用程序在某些机器上工作而在其他机器上不工作。。。使用相同的VM选项,以及(我猜)处理器架构和JVM版本 如果这是一个问题,OP将需要添加更多的物理内存或增加系统的交换空间 要扩展@BalusC的第二个解决方案,OP可能需要更改应用程序,以便在启动时不急于加载映像。相反,它可以延迟加载它们,并使用具有弱引用的缓存来确保GC可以在内存紧张时丢弃它们。
然而,如果预加载所有映像是至关重要的,那么OP别无选择,只能找出如何给JVM一个更大的堆;见上文。发现问题时,我正试图将6144x6144 PNG加载到我的程序中
将映像大小重新调整为256x256 TGA后,程序将正常加载,不会出现错误。根据具体情况,它可能是2005年以来出现的JVM错误的表现 如果查看java.nio.DirectByteBuffer类中的代码,您将看到它创建了一个线程来释放请求的内存。如果您编程使用这个类的大量实例(例如间接通过IOUtils),即使您有足够的内存,也可能得到OOME。只是线程没有得到释放内存的机会 这是一个令人讨厌的问题
当您遇到此特定异常时,堆栈跟踪以不安全的
结尾。allocateMemory(本机方法)
表示操作系统拒绝了分配更多内存的请求;表示已达到JVM Java堆内存限制的异常将具有不同的堆栈跟踪
因此,可用的修复方法是:在应用程序中的某个位置保存一些内存,购买更多的物理RAM(或更大的驱动器,以便有更多的空间用于交换文件),或者检查是否可以配置操作系统以允许更多内存分配,例如通过增加交换空间
如果您在这种情况下分配常规Java对象(而不是本机内存缓冲区或非常大的原语数组),我只建议您重写代码以节省内存,或者使用具有更多RAM的机器;由于垃圾收集器需要遍历堆上的每个可访问对象,以便将它们标记为活动对象,这意味着您将不引用的对象通常仍必须由JVM定期提取到内存中……因此,对小型Java对象使用大量交换变得相当昂贵
对于许多大型映像,我建议只使用软引用来保存您认为可能需要的映像,这允许JVM在需要内存时将它们从内存中删除,但如果可行,则鼓励JVM将它们保存在内存中,以避免定期重新加载它们的性能问题