JMagick 和 JVM 崩溃
我正在使用 JMagick 并有一个简单的 Java 类,该类循环遍历目录中的所有图像(并且其子目录),将图像转换为灰度图像。
我的应用程序运行一段时间后,JVM 崩溃了。我相信日志中的错误消息可能表明存在内存问题:
Java 框架:(J=编译的 Java 代码,j=解释的,Vv=VM 代码)j magick.MagickImage.writeImage(Lmagick/ImageInfo;)Z+0 j com.example.ImageGenerator.generateAlternativeImages(Ljava/io/File;Z)V+91 j com.example.ImageGenerator.main([Ljava/lang/String;)V+58 v ~StubRoutines::call_stub
--------------- 过程 ---------------
Java 线程:( => 当前线程)0x0ab0c800 JavaThread“低 内存检测器”守护进程 [_thread_blocked, id=1532, 堆栈(0x0aec0000,0x0af10000)] 0x0ab0ac00 JavaThread “CompilerThread0”守护进程 [_thread_blocked,id=7304, 堆栈(0x0ae70000,0x0aec0000)] 0x0aafe000 JavaThread“JDWP命令 Reader”守护进程[_thread_in_native,id=6836, 堆栈(0x0ae20000,0x0ae70000)] 0x0aafc800 JavaThread“JDWP事件 辅助线程”守护进程 [_thread_blocked, id=7248, 堆栈(0x0add0000,0x0ae20000)] 0x0aafa400 JavaThread“JDWP传输 侦听器:dt_socket”守护进程 [_thread_blocked,id=6252, stack(0x0ad80000,0x0add0000)] 0x0aaee800 JavaThread "附加 监听器”守护进程 [_thread_blocked, id=2020, 堆栈(0x0aca0000,0x0acf0000)] 0x0aaed400 JavaThread“信号 调度程序”守护进程 [_thread_blocked, id=7492, 堆栈(0x0ac50000,0x0aca0000)] 0x0aada400 JavaThread“终结器” 守护进程 [_thread_blocked,id=5400,堆栈(0x0ac00000,0x0ac50000)]
0x0aad8c00 JavaThread“参考处理程序”守护进程[_thread_blocked, id=5772,堆栈(0x0abb0000,0x0ac00000)] =>0x002b8000 JavaThread“主”[_thread_in_native,id = 7020, 堆栈(0x008c0000,0x00910000)]其他线程:0x0aad5400 VMThread [堆栈:0x0ab60000,0x0abb0000] [id=7720] 0x0ab0f000 WatcherThread [堆栈:0x0af10000,0x0af60000] [id=6432]
虚拟机状态:未处于安全点(正常执行)
线程当前拥有的 VM 互斥体/监视器:无
堆定义新生代总计 960K,已使用 793K [0x029c0000, 0x02ac0000, 0x02ea0000) 伊甸园空间 896K, 已使用 88% [0x029c0000, 0x02a865f0, 0x02aa0000) 来自空间 64K, 0% 使用 [0x02aa0000, 0x02aa0000, 0x02ab0000) 到空间 64K, 0% 使用 [0x02ab0000, 0x02ab0000、0x02ac0000) 终身代总计 4096K,已使用 0K [0x02ea0000, 0x032a0000, 0x069c0000) 空间4096K, 已使用0% [0x02ea0000, 0x02ea0000, 0x02ea0200, 0x032a0000) 压缩永久代 总共12288K,使用了2219K [0x069c0000, 0x075c0000, 0x0a9c0000) 空间 12288K,已使用 18% [0x069c0000、0x06bead18、0x06beae00、 0x075c0000) 未配置共享空间。
我尝试添加 -Xmx 选项,但认为这可能不是解决方案。有什么建议吗?
提前致谢。
I'm using JMagick and have a simple Java class that loops over all images in a directory (and its sub directories), converting images into grayscale images.
After my application runs for a while the JVM crashes. I believe the error message in the log is possibly suggesting that there were memory issues:
Java frames: (J=compiled Java code, j=interpreted, Vv=VM code) j
magick.MagickImage.writeImage(Lmagick/ImageInfo;)Z+0 j
com.example.ImageGenerator.generateAlternativeImages(Ljava/io/File;Z)V+91
j com.example.ImageGenerator.main([Ljava/lang/String;)V+58 v
~StubRoutines::call_stub--------------- P R O C E S S ---------------
Java Threads: ( => current thread ) 0x0ab0c800 JavaThread "Low
Memory Detector" daemon [_thread_blocked, id=1532,
stack(0x0aec0000,0x0af10000)] 0x0ab0ac00 JavaThread
"CompilerThread0" daemon [_thread_blocked, id=7304,
stack(0x0ae70000,0x0aec0000)] 0x0aafe000 JavaThread "JDWP Command
Reader" daemon [_thread_in_native, id=6836,
stack(0x0ae20000,0x0ae70000)] 0x0aafc800 JavaThread "JDWP Event
Helper Thread" daemon [_thread_blocked, id=7248,
stack(0x0add0000,0x0ae20000)] 0x0aafa400 JavaThread "JDWP Transport
Listener: dt_socket" daemon [_thread_blocked, id=6252,
stack(0x0ad80000,0x0add0000)] 0x0aaee800 JavaThread "Attach
Listener" daemon [_thread_blocked, id=2020,
stack(0x0aca0000,0x0acf0000)] 0x0aaed400 JavaThread "Signal
Dispatcher" daemon [_thread_blocked, id=7492,
stack(0x0ac50000,0x0aca0000)] 0x0aada400 JavaThread "Finalizer"
daemon [_thread_blocked, id=5400, stack(0x0ac00000,0x0ac50000)]
0x0aad8c00 JavaThread "Reference Handler" daemon [_thread_blocked,
id=5772, stack(0x0abb0000,0x0ac00000)]
=>0x002b8000 JavaThread "main" [_thread_in_native, id=7020,
stack(0x008c0000,0x00910000)]Other Threads: 0x0aad5400 VMThread [stack: 0x0ab60000,0x0abb0000]
[id=7720] 0x0ab0f000 WatcherThread [stack: 0x0af10000,0x0af60000]
[id=6432]VM state:not at safepoint (normal execution)
VM Mutex/Monitor currently owned by a thread: None
Heap def new generation total 960K, used 793K [0x029c0000,
0x02ac0000, 0x02ea0000) eden space 896K, 88% used [0x029c0000,
0x02a865f0, 0x02aa0000) from space 64K, 0% used [0x02aa0000,
0x02aa0000, 0x02ab0000) to space 64K, 0% used [0x02ab0000,
0x02ab0000, 0x02ac0000) tenured generation total 4096K, used 0K
[0x02ea0000, 0x032a0000, 0x069c0000) the space 4096K, 0% used
[0x02ea0000, 0x02ea0000, 0x02ea0200, 0x032a0000) compacting perm gen
total 12288K, used 2219K [0x069c0000, 0x075c0000, 0x0a9c0000) the
space 12288K, 18% used [0x069c0000, 0x06bead18, 0x06beae00,
0x075c0000) No shared spaces configured.
I've tried adding -Xmx options but figure this might not be the solution. Any suggestions?
Thanks in advance.
如果你对这篇内容有疑问,欢迎到本站社区发帖提问 参与讨论,获取更多帮助,或者扫码二维码加入 Web 技术交流群。
绑定邮箱获取回复消息
由于您还没有绑定你的真实邮箱,如果其他用户或者作者回复了您的评论,将不能在第一时间通知您!
发布评论
评论(3)
你的 JVM 崩溃了,
-Xmx
没有帮助。您可以尝试使用-Xint
运行并看看是否可以重现该问题吗?这将告诉 JVM 在没有热点的情况下运行,这意味着没有动态编译优化。您运行的是哪个版本的 JVM?如果您无法使用-Xint
重现问题,并且您使用的是最新的 JVM,则可以尝试仅排除magick.MagickImage.writeImage
进行编译。要排除,请在应用程序工作目录中创建一个名为:的文件
并添加以下行:
Your JVM crashed,
-Xmx
will not help. Can you try running with-Xint
and see if you can reproduce the problem? This will tell the JVM to run without Hotspot, which means no dynamic compilation optimizations. Which version of the JVM are you running with? If you can't reproduce the problem with-Xint
, and you're using the latest JVM, you can try excluding onlymagick.MagickImage.writeImage
from being compiled.To exclude, create a file in the applications working directory called:
and add the line :
如果您怀疑这是内存问题,请使用选项 -XX:+HeapDumpOnOutOfMemoryError 运行应用程序。如果应用程序因 OOME 崩溃,这将创建堆转储。然后,您可以使用 jhat 或 eclipse mat 等工具分析堆转储。
您还可以使用 jmap 生成正在运行的应用程序的堆转储,并使用上面建议的工具查看内存消耗,以确定您的怀疑。
If you suspect it to be a memory issue then run the application with the option -XX:+HeapDumpOnOutOfMemoryError. This will create a heap dump if the application crashes due to OOME. You can then analyze the heap dump using tools like jhat or eclipse mat.
You can also generate the heap dump of a running application using jmap and see the memory consumption using the tools suggested above to be sure of your suspicion.
我发现您需要销毁您创建的每个图像副本。否则会造成内存泄漏。它正在使用 JNI,我认为有一些 malloc 需要释放。
I found that you need to destroy every image copy you create. Otherwise you create a memory leak. It is using JNI and I think there are mallocs which need to be freed.