类加载期间 memcpy 时 JVM 崩溃
我的 JVM 崩溃了,hs_err 文件显示它在尝试加载类时崩溃了。特别是在尝试 memcpy ([libc.so.6+0x6aa2c] memcpy+0x1c) 时。我查看了 .class 文件并能够确定正在加载什么类。
但谁能告诉我什么可能导致这种情况,或者我如何确定更多有关原因的信息?如果 JVM 内存不足,它不会抛出错误。任何见解都将受到高度赞赏。
我包含了 hs_err 文件的摘录。
#
# An unexpected error has been detected by Java Runtime Environment:
#
# SIGBUS (0x7) at pc=0x005aba2c, pid=20841, tid=2427227056
#
# Java VM: Java HotSpot(TM) Client VM (1.6.0_02-b05 mixed mode)
# Problematic frame:
# C [libc.so.6+0x6aa2c] memcpy+0x1c
#
# If you would like to submit a bug report, please visit:
# http://java.sun.com/webapps/bugreport/crash.jsp
#
--------------- T H R E A D ---------------
Current thread (0x90d0dc00): JavaThread "ORDERHANDLER" [_thread_in_native, id=20881]
siginfo:si_signo=7, si_errno=0, si_code=2, si_addr=0x915e3000
Registers:
EAX=0x91218298, EBX=0xb7f2e71c, ECX=0x0000079b, EDX=0x915dfef2
ESP=0x90ac6a34, EBP=0x90ac6a60, ESI=0x915e2ffd, EDI=0x914f0a0d
EIP=0x005aba2c, CR2=0x915e3000, EFLAGS=0x00010206
Top of Stack: (sp=0x90ac6a34)
0x90ac6a34: b7f29d4b 914ed930 915dff20 00004f49
0x90ac6a44: 082e7bc4 00006f6f 00004243 00004f49
0x90ac6a54: b7f2e71c 080e3e54 00000000 90ac6a90
0x90ac6a64: b7f29fbb 080e3b00 080e3e54 00000000
0x90ac6a74: 00000000 90d0dc00 00000000 d68dd1b6
0x90ac6a84: b7f2e71c 90ac6ad8 90d0dcec 90ac6f00
0x90ac6a94: b7f21169 080e3b00 90ac6ad8 0000002b
0x90ac6aa4: 0000002b 90ac6ad8 00000008 00000000
Instructions: (pc=0x005aba2c)
0x005aba1c: 8b 74 24 08 fc d1 e9 73 01 a4 d1 e9 73 02 66 a5
0x005aba2c: f3 a5 89 c7 89 d6 8b 44 24 04 c3 90 90 90 90 90
Stack: [0x90a78000,0x90ac9000), sp=0x90ac6a34, free space=314k
Native frames: (J=compiled Java code, j=interpreted, Vv=VM code, C=native code)
C [libc.so.6+0x6aa2c] memcpy+0x1c
C [libzip.so+0xbfbb] ZIP_GetEntry+0x10b
C [libzip.so+0x3169] Java_java_util_zip_ZipFile_getEntry+0xc9
J java.util.zip.ZipFile.getEntry(JLjava/lang/String;Z)J
J java.util.zip.ZipFile.getEntry(Ljava/lang/String;)Ljava/util/zip/ZipEntry;
J java.util.jar.JarFile.getEntry(Ljava/lang/String;)Ljava/util/zip/ZipEntry;
J sun.misc.URLClassPath$JarLoader.getResource(Ljava/lang/String;Z)Lsun/misc/Resource;
J sun.misc.URLClassPath.getResource(Ljava/lang/String;Z)Lsun/misc/Resource;
J java.net.URLClassLoader$1.run()Ljava/lang/Object;
v ~StubRoutines::call_stub
V [libjvm.so+0x20bbbd]
V [libjvm.so+0x30a6b8]
V [libjvm.so+0x20ba50]
V [libjvm.so+0x26190b]
C [libjava.so+0xaa5c] Java_java_security_AccessController_doPrivileged__Ljava_security_PrivilegedExceptionAction_2Ljava_security_AccessControlContext_2+0x3
c
J java.security.AccessController.doPrivileged(Ljava/security/PrivilegedExceptionAction;Ljava/security/AccessControlContext;)Ljava/lang/Object;
J java.net.URLClassLoader.findClass(Ljava/lang/String;)Ljava/lang/Class;
J java.lang.ClassLoader.loadClass(Ljava/lang/String;Z)Ljava/lang/Class;
J sun.misc.Launcher$AppClassLoader.loadClass(Ljava/lang/String;Z)Ljava/lang/Class;
j java.lang.ClassLoader.loadClass(Ljava/lang/String;)Ljava/lang/Class;+3
j java.lang.ClassLoader.loadClassInternal(Ljava/lang/String;)Ljava/lang/Class;+2
v ~StubRoutines::call_stub
V [libjvm.so+0x20bbbd]
V [libjvm.so+0x30a6b8]
V [libjvm.so+0x20b6e1]
V [libjvm.so+0x20b7ca]
V [libjvm.so+0x367621]
V [libjvm.so+0x3662a5]
V [libjvm.so+0x365357]
V [libjvm.so+0x365112]
V [libjvm.so+0x1adb03]
V [libjvm.so+0x1aeb32]
V [libjvm.so+0x2d75cb]
V [libjvm.so+0x2d8a94]
V [libjvm.so+0x2d8a17]
V [libjvm.so+0x1fe7f8]
j com.aqua.foms.book.OrderHandler.handleNewOrder(Lcom/aqua/NmsApi/OrderMap;Lcom/aqua/api/AtsMessage;)V+221
j com.aqua.foms.book.FMSNewOrderTask.execute()V+12
j com.aqua.api.EEDefaultWorkerThread.run()V+96
v ~StubRoutines::call_stub
V [libjvm.so+0x20bbbd]
V [libjvm.so+0x30a6b8]
V [libjvm.so+0x20b4d0]
V [libjvm.so+0x20b55d]
V [libjvm.so+0x27b795]
V [libjvm.so+0x383ef0]
V [libjvm.so+0x30b5a9]
C [libpthread.so.0+0x5371]
Java frames: (J=compiled Java code, j=interpreted, Vv=VM code)
J java.util.zip.ZipFile.getEntry(JLjava/lang/String;Z)J
J java.util.zip.ZipFile.getEntry(Ljava/lang/String;)Ljava/util/zip/ZipEntry;
J java.util.jar.JarFile.getEntry(Ljava/lang/String;)Ljava/util/zip/ZipEntry;
J sun.misc.URLClassPath$JarLoader.getResource(Ljava/lang/String;Z)Lsun/misc/Resource;
J sun.misc.URLClassPath.getResource(Ljava/lang/String;Z)Lsun/misc/Resource;
J java.net.URLClassLoader$1.run()Ljava/lang/Object;
v ~StubRoutines::call_stub
J java.security.AccessController.doPrivileged(Ljava/security/PrivilegedExceptionAction;Ljava/security/AccessControlContext;)Ljava/lang/Object;
J java.net.URLClassLoader.findClass(Ljava/lang/String;)Ljava/lang/Class;
J java.lang.ClassLoader.loadClass(Ljava/lang/String;Z)Ljava/lang/Class;
J sun.misc.Launcher$AppClassLoader.loadClass(Ljava/lang/String;Z)Ljava/lang/Class;
j java.lang.ClassLoader.loadClass(Ljava/lang/String;)Ljava/lang/Class;+3
j java.lang.ClassLoader.loadClassInternal(Ljava/lang/String;)Ljava/lang/Class;+2
v ~StubRoutines::call_stub
j com.aqua.foms.book.OrderHandler.handleNewOrder(Lcom/aqua/NmsApi/OrderMap;Lcom/aqua/api/AtsMessage;)V+221
j com.aqua.foms.book.FMSNewOrderTask.execute()V+12
j com.aqua.api.EEDefaultWorkerThread.run()V+96
v ~StubRoutines::call_stub
--------------- P R O C E S S ---------------
Java Threads: ( => current thread )
0x080c9c00 JavaThread "pool-1-thread-3" [_thread_blocked, id=18725]
0x0824f800 JavaThread "pool-1-thread-2" [_thread_blocked, id=13693]
0x91217c00 JavaThread "AquaSchedulerService_7" daemon [_thread_blocked, id=23675]
0x91215c00 JavaThread "AquaSchedulerService_6" daemon [_thread_blocked, id=23001]
0x91215400 JavaThread "AquaSchedulerService_5" daemon [_thread_blocked, id=22759]
0x91213400 JavaThread "AquaSchedulerService_4" daemon [_thread_blocked, id=22410]
0x91212c00 JavaThread "AquaSchedulerService_3" daemon [_thread_blocked, id=22262]
0x08316400 JavaThread "pool-1-thread-1" [_thread_blocked, id=22260]
0x0827d000 JavaThread "JmsConn_1_sender_0" daemon [_thread_blocked, id=21196]
0x90d0cc00 JavaThread "Timer-0" [_thread_blocked, id=20882]
=>0x90d0dc00 JavaThread "ORDERHANDLER" [_thread_in_native, id=20881]
0x90d0d400 JavaThread "TradeInviteMonitor" [_thread_blocked, id=20880]
0x90d09c00 JavaThread "ROUTERT" [_thread_blocked, id=20878]
0x90d09000 JavaThread "TIBCO EMS Session Dispatcher (33197)" [_thread_blocked, id=20877]
0x08310800 JavaThread "DORDERHANDLER" [_thread_blocked, id=20874]
0x90d01c00 JavaThread "Thread-12" daemon [_thread_blocked, id=20873]
0x90d03000 JavaThread "Thread-11" daemon [_thread_in_native, id=20872]
0x082e1c00 JavaThread "DELAYEDORDMON" [_thread_blocked, id=20871]
0x082e8000 JavaThread "DBUPD" [_thread_blocked, id=20870]
0x914e5000 JavaThread "pool-2-thread-1" [_thread_blocked, id=20869]
0x914e3c00 JavaThread "StatusStatsEventDispatcherThread" [_thread_blocked, id=20868]
0x082c8400 JavaThread "TimerQueue" daemon [_thread_blocked, id=20866]
0x082ca000 JavaThread "MDATATHREAD" [_thread_blocked, id=20865]
0x082c9400 JavaThread "AquaSchedulerService_2" daemon [_thread_blocked, id=20864]
0x9122b000 JavaThread "DestroyJavaVM" [_thread_blocked, id=20843]
0x91200800 JavaThread "FirmMatchingServer" [_thread_blocked, id=20863]
0x914de800 JavaThread "TIBCO EMS TCPLink Reader (32084)" daemon [_thread_in_native, id=20861]
0x9122a400 JavaThread "TIBCO EMS Connections Pinger" daemon [_thread_blocked, id=20859]
0x914d4000 JavaThread "WDISTQ" [_thread_blocked, id=20858]
0x9121f400 JavaThread "JmsConn_1_connector_0" daemon [_thread_blocked, id=20857]
0x914d8000 JavaThread "JmsConn_1_receiver_0" daemon [_thread_blocked, id=20856]
0x9149ac00 JavaThread "AquaSchedulerService_1" daemon [_thread_blocked, id=20855]
0x9149b400 JavaThread "AquaSchedulerService_0" daemon [_thread_blocked, id=20854]
0x9142a000 JavaThread "MySQL Statement Cancellation Timer" daemon [_thread_blocked, id=20852]
0x91425c00 JavaThread "Dispatcher-Thread-0" daemon [_thread_blocked, id=20851]
0x080bf800 JavaThread "Low Memory Detector" daemon [_thread_blocked, id=20849]
0x080bdc00 JavaThread "CompilerThread0" daemon [_thread_blocked, id=20848]
0x080bcc00 JavaThread "Signal Dispatcher" daemon [_thread_blocked, id=20847]
0x080a9800 JavaThread "Finalizer" daemon [_thread_blocked, id=20846]
0x080a8800 JavaThread "Reference Handler" daemon [_thread_blocked, id=20845]
Other Threads:
0x080a5400 VMThread [id=20844]
0x080c1000 WatcherThread [id=20850]
VM state:not at safepoint (normal execution)
VM Mutex/Monitor currently owned by a thread: None
My JVM crashed the and the hs_err file showed that it crashed while attempting to load a class. Specifically while trying to memcpy ([libc.so.6+0x6aa2c] memcpy+0x1c). I looked at the .class file and was able to determine what class was being loaded.
But can any one tell me what could cause this or how i could determine more about the cause? If the JVM was out of memory wouldn't it throw an Error. Any insight is greatly appreciated.
I've included an excerpt from my hs_err file.
#
# An unexpected error has been detected by Java Runtime Environment:
#
# SIGBUS (0x7) at pc=0x005aba2c, pid=20841, tid=2427227056
#
# Java VM: Java HotSpot(TM) Client VM (1.6.0_02-b05 mixed mode)
# Problematic frame:
# C [libc.so.6+0x6aa2c] memcpy+0x1c
#
# If you would like to submit a bug report, please visit:
# http://java.sun.com/webapps/bugreport/crash.jsp
#
--------------- T H R E A D ---------------
Current thread (0x90d0dc00): JavaThread "ORDERHANDLER" [_thread_in_native, id=20881]
siginfo:si_signo=7, si_errno=0, si_code=2, si_addr=0x915e3000
Registers:
EAX=0x91218298, EBX=0xb7f2e71c, ECX=0x0000079b, EDX=0x915dfef2
ESP=0x90ac6a34, EBP=0x90ac6a60, ESI=0x915e2ffd, EDI=0x914f0a0d
EIP=0x005aba2c, CR2=0x915e3000, EFLAGS=0x00010206
Top of Stack: (sp=0x90ac6a34)
0x90ac6a34: b7f29d4b 914ed930 915dff20 00004f49
0x90ac6a44: 082e7bc4 00006f6f 00004243 00004f49
0x90ac6a54: b7f2e71c 080e3e54 00000000 90ac6a90
0x90ac6a64: b7f29fbb 080e3b00 080e3e54 00000000
0x90ac6a74: 00000000 90d0dc00 00000000 d68dd1b6
0x90ac6a84: b7f2e71c 90ac6ad8 90d0dcec 90ac6f00
0x90ac6a94: b7f21169 080e3b00 90ac6ad8 0000002b
0x90ac6aa4: 0000002b 90ac6ad8 00000008 00000000
Instructions: (pc=0x005aba2c)
0x005aba1c: 8b 74 24 08 fc d1 e9 73 01 a4 d1 e9 73 02 66 a5
0x005aba2c: f3 a5 89 c7 89 d6 8b 44 24 04 c3 90 90 90 90 90
Stack: [0x90a78000,0x90ac9000), sp=0x90ac6a34, free space=314k
Native frames: (J=compiled Java code, j=interpreted, Vv=VM code, C=native code)
C [libc.so.6+0x6aa2c] memcpy+0x1c
C [libzip.so+0xbfbb] ZIP_GetEntry+0x10b
C [libzip.so+0x3169] Java_java_util_zip_ZipFile_getEntry+0xc9
J java.util.zip.ZipFile.getEntry(JLjava/lang/String;Z)J
J java.util.zip.ZipFile.getEntry(Ljava/lang/String;)Ljava/util/zip/ZipEntry;
J java.util.jar.JarFile.getEntry(Ljava/lang/String;)Ljava/util/zip/ZipEntry;
J sun.misc.URLClassPath$JarLoader.getResource(Ljava/lang/String;Z)Lsun/misc/Resource;
J sun.misc.URLClassPath.getResource(Ljava/lang/String;Z)Lsun/misc/Resource;
J java.net.URLClassLoader$1.run()Ljava/lang/Object;
v ~StubRoutines::call_stub
V [libjvm.so+0x20bbbd]
V [libjvm.so+0x30a6b8]
V [libjvm.so+0x20ba50]
V [libjvm.so+0x26190b]
C [libjava.so+0xaa5c] Java_java_security_AccessController_doPrivileged__Ljava_security_PrivilegedExceptionAction_2Ljava_security_AccessControlContext_2+0x3
c
J java.security.AccessController.doPrivileged(Ljava/security/PrivilegedExceptionAction;Ljava/security/AccessControlContext;)Ljava/lang/Object;
J java.net.URLClassLoader.findClass(Ljava/lang/String;)Ljava/lang/Class;
J java.lang.ClassLoader.loadClass(Ljava/lang/String;Z)Ljava/lang/Class;
J sun.misc.Launcher$AppClassLoader.loadClass(Ljava/lang/String;Z)Ljava/lang/Class;
j java.lang.ClassLoader.loadClass(Ljava/lang/String;)Ljava/lang/Class;+3
j java.lang.ClassLoader.loadClassInternal(Ljava/lang/String;)Ljava/lang/Class;+2
v ~StubRoutines::call_stub
V [libjvm.so+0x20bbbd]
V [libjvm.so+0x30a6b8]
V [libjvm.so+0x20b6e1]
V [libjvm.so+0x20b7ca]
V [libjvm.so+0x367621]
V [libjvm.so+0x3662a5]
V [libjvm.so+0x365357]
V [libjvm.so+0x365112]
V [libjvm.so+0x1adb03]
V [libjvm.so+0x1aeb32]
V [libjvm.so+0x2d75cb]
V [libjvm.so+0x2d8a94]
V [libjvm.so+0x2d8a17]
V [libjvm.so+0x1fe7f8]
j com.aqua.foms.book.OrderHandler.handleNewOrder(Lcom/aqua/NmsApi/OrderMap;Lcom/aqua/api/AtsMessage;)V+221
j com.aqua.foms.book.FMSNewOrderTask.execute()V+12
j com.aqua.api.EEDefaultWorkerThread.run()V+96
v ~StubRoutines::call_stub
V [libjvm.so+0x20bbbd]
V [libjvm.so+0x30a6b8]
V [libjvm.so+0x20b4d0]
V [libjvm.so+0x20b55d]
V [libjvm.so+0x27b795]
V [libjvm.so+0x383ef0]
V [libjvm.so+0x30b5a9]
C [libpthread.so.0+0x5371]
Java frames: (J=compiled Java code, j=interpreted, Vv=VM code)
J java.util.zip.ZipFile.getEntry(JLjava/lang/String;Z)J
J java.util.zip.ZipFile.getEntry(Ljava/lang/String;)Ljava/util/zip/ZipEntry;
J java.util.jar.JarFile.getEntry(Ljava/lang/String;)Ljava/util/zip/ZipEntry;
J sun.misc.URLClassPath$JarLoader.getResource(Ljava/lang/String;Z)Lsun/misc/Resource;
J sun.misc.URLClassPath.getResource(Ljava/lang/String;Z)Lsun/misc/Resource;
J java.net.URLClassLoader$1.run()Ljava/lang/Object;
v ~StubRoutines::call_stub
J java.security.AccessController.doPrivileged(Ljava/security/PrivilegedExceptionAction;Ljava/security/AccessControlContext;)Ljava/lang/Object;
J java.net.URLClassLoader.findClass(Ljava/lang/String;)Ljava/lang/Class;
J java.lang.ClassLoader.loadClass(Ljava/lang/String;Z)Ljava/lang/Class;
J sun.misc.Launcher$AppClassLoader.loadClass(Ljava/lang/String;Z)Ljava/lang/Class;
j java.lang.ClassLoader.loadClass(Ljava/lang/String;)Ljava/lang/Class;+3
j java.lang.ClassLoader.loadClassInternal(Ljava/lang/String;)Ljava/lang/Class;+2
v ~StubRoutines::call_stub
j com.aqua.foms.book.OrderHandler.handleNewOrder(Lcom/aqua/NmsApi/OrderMap;Lcom/aqua/api/AtsMessage;)V+221
j com.aqua.foms.book.FMSNewOrderTask.execute()V+12
j com.aqua.api.EEDefaultWorkerThread.run()V+96
v ~StubRoutines::call_stub
--------------- P R O C E S S ---------------
Java Threads: ( => current thread )
0x080c9c00 JavaThread "pool-1-thread-3" [_thread_blocked, id=18725]
0x0824f800 JavaThread "pool-1-thread-2" [_thread_blocked, id=13693]
0x91217c00 JavaThread "AquaSchedulerService_7" daemon [_thread_blocked, id=23675]
0x91215c00 JavaThread "AquaSchedulerService_6" daemon [_thread_blocked, id=23001]
0x91215400 JavaThread "AquaSchedulerService_5" daemon [_thread_blocked, id=22759]
0x91213400 JavaThread "AquaSchedulerService_4" daemon [_thread_blocked, id=22410]
0x91212c00 JavaThread "AquaSchedulerService_3" daemon [_thread_blocked, id=22262]
0x08316400 JavaThread "pool-1-thread-1" [_thread_blocked, id=22260]
0x0827d000 JavaThread "JmsConn_1_sender_0" daemon [_thread_blocked, id=21196]
0x90d0cc00 JavaThread "Timer-0" [_thread_blocked, id=20882]
=>0x90d0dc00 JavaThread "ORDERHANDLER" [_thread_in_native, id=20881]
0x90d0d400 JavaThread "TradeInviteMonitor" [_thread_blocked, id=20880]
0x90d09c00 JavaThread "ROUTERT" [_thread_blocked, id=20878]
0x90d09000 JavaThread "TIBCO EMS Session Dispatcher (33197)" [_thread_blocked, id=20877]
0x08310800 JavaThread "DORDERHANDLER" [_thread_blocked, id=20874]
0x90d01c00 JavaThread "Thread-12" daemon [_thread_blocked, id=20873]
0x90d03000 JavaThread "Thread-11" daemon [_thread_in_native, id=20872]
0x082e1c00 JavaThread "DELAYEDORDMON" [_thread_blocked, id=20871]
0x082e8000 JavaThread "DBUPD" [_thread_blocked, id=20870]
0x914e5000 JavaThread "pool-2-thread-1" [_thread_blocked, id=20869]
0x914e3c00 JavaThread "StatusStatsEventDispatcherThread" [_thread_blocked, id=20868]
0x082c8400 JavaThread "TimerQueue" daemon [_thread_blocked, id=20866]
0x082ca000 JavaThread "MDATATHREAD" [_thread_blocked, id=20865]
0x082c9400 JavaThread "AquaSchedulerService_2" daemon [_thread_blocked, id=20864]
0x9122b000 JavaThread "DestroyJavaVM" [_thread_blocked, id=20843]
0x91200800 JavaThread "FirmMatchingServer" [_thread_blocked, id=20863]
0x914de800 JavaThread "TIBCO EMS TCPLink Reader (32084)" daemon [_thread_in_native, id=20861]
0x9122a400 JavaThread "TIBCO EMS Connections Pinger" daemon [_thread_blocked, id=20859]
0x914d4000 JavaThread "WDISTQ" [_thread_blocked, id=20858]
0x9121f400 JavaThread "JmsConn_1_connector_0" daemon [_thread_blocked, id=20857]
0x914d8000 JavaThread "JmsConn_1_receiver_0" daemon [_thread_blocked, id=20856]
0x9149ac00 JavaThread "AquaSchedulerService_1" daemon [_thread_blocked, id=20855]
0x9149b400 JavaThread "AquaSchedulerService_0" daemon [_thread_blocked, id=20854]
0x9142a000 JavaThread "MySQL Statement Cancellation Timer" daemon [_thread_blocked, id=20852]
0x91425c00 JavaThread "Dispatcher-Thread-0" daemon [_thread_blocked, id=20851]
0x080bf800 JavaThread "Low Memory Detector" daemon [_thread_blocked, id=20849]
0x080bdc00 JavaThread "CompilerThread0" daemon [_thread_blocked, id=20848]
0x080bcc00 JavaThread "Signal Dispatcher" daemon [_thread_blocked, id=20847]
0x080a9800 JavaThread "Finalizer" daemon [_thread_blocked, id=20846]
0x080a8800 JavaThread "Reference Handler" daemon [_thread_blocked, id=20845]
Other Threads:
0x080a5400 VMThread [id=20844]
0x080c1000 WatcherThread [id=20850]
VM state:not at safepoint (normal execution)
VM Mutex/Monitor currently owned by a thread: None
如果你对这篇内容有疑问,欢迎到本站社区发帖提问 参与讨论,获取更多帮助,或者扫码二维码加入 Web 技术交流群。
绑定邮箱获取回复消息
由于您还没有绑定你的真实邮箱,如果其他用户或者作者回复了您的评论,将不能在第一时间通知您!
发布评论
评论(5)
我们也见过类似的错误。我们当前的怀疑是在进程运行时(通过升级进程)重写的 jar 文件。
we've seen similar errors. our current suspect is jar files which are re-written (by an upgrade process) while the process is running.
答案1是正确的。 java.util.zip.* 的实现有错误。
如果替换 Java 程序当前“打开”的 zip/jar 文件(已缓存 ZipFile/JarFile 对象),它将使用从原始文件读取的缓存目录 (TOC) 数据,并尝试并用它来解压替换文件中的数据。通货膨胀代码并不健壮,当出现错误数据时会彻底崩溃。
普通的 UNIX 程序在使用文件时会保持文件打开状态。如果覆盖该文件,使用该文件的程序仍然可以通过打开的文件描述符访问它打开的原始文件。
OpenJDK 的 java.util.zip.* 实现选择不为 zip/jar 文件保持文件描述符打开。原因之一可能是 Java 经常在类路径中使用数百个 jar 文件来调用,而设计者不想仅使用 jar 文件上的数百个文件描述符,而不会为程序本身留下任何文件描述符。因此,一旦读取了 jar/zip 内容表,他们就会关闭文件描述符,并且如果其内容发生更改,则将永久失去对原始 jar/zip 文件的访问权限。
无论出于何种原因,ZipFile 不会或无法告知 zip/jar 文件已更改。如果确实如此,它可能会重新读取目录或抛出某种错误(如果不可能)。
此外,即使 TOC 仍然有效,充气器也会因错误数据而崩溃。如果 ZIP 目录有效但压缩的数据流是故意错误的怎么办?
这是一个测试程序,证明 java.util.zip.* 不会为 zip/jar 文件保持文件描述符打开状态,并且不会检测到 zip 文件已更改。
运行此程序应该会导致 JVM 崩溃:
为此针对 JVM 提交的主要错误是 JDK-4425695:更新 jar 文件会使正在运行的程序崩溃。
RFE 6929479:添加系统属性 sun.zip.disableMemoryMapping 以禁用 mmap 使用ZipFile 在 JDK7 中实现了一个系统属性 -
sun.zip.disableMemoryMapping
- 您可以将其用作解决方法。Answer 1 is correct. The implementation of java.util.zip.* is at fault.
If you replace a zip/jar file that a Java program currently has "open" (has cached the ZipFile/JarFile object), it will use cached table-of-contents (TOC) data it read from the original file, and will try and use that to unpack data in the replaced file. The inflation code is not robust and will outright crash when presented with bad data.
Normal unix programs keep files open while they're working with them. If you overwrite the file, the program using it still has access to the original that it opened, by virtue of the open file descriptor.
OpenJDK's java.util.zip.* implementation chose not to keep file descriptors open for zip/jar files. One reason for this could be that Java is often invoked with hundreds of jar files in the class path, and the designers didn't want to use up hundreds of file descriptors on the jar files alone, leaving none left for the program itself. So they close file descriptors as soon as they've read the jar/zip table of contents, and permanently lose access to the original jar/zip file, should its contents change.
For whatever reason, ZipFile does not or cannot tell a zip/jar file has changed. If it did, it could re-read the TOC or throw some kind of Error if that's not possible.
Furthermore, even if the TOC remained valid, it's a problem that the inflater crashes on faulty data. What if the ZIP table-of-contents was valid but the deflated data stream was deliberately wrong?
Here's a test program that proves java.util.zip.* doesn't keep file descriptors open for zip/jar files and doesn't detect that the zip file has changed.
Running this program should give you a JVM crash:
The main bug filed against the JVM for this is JDK-4425695 : Updating jar files crashes running programs.
RFE 6929479: Add a system property sun.zip.disableMemoryMapping to disable mmap use in ZipFile implements a system property in JDK7 -
sun.zip.disableMemoryMapping
- which you could use as a workaround.问题是 zip/JAR 文件在使用时被覆盖。
ZIP 文件格式的 OpenJDK 代码是本机 C 代码,任何条目查找、创建都需要多次往返昂贵的 jni 调用。
当前的本机 C 实现代码使用 mmap 来映射中央目录表,当底层 jar 文件被新内容覆盖而仍被其他 ZipFile 使用时,这会带来 vm 崩溃的很大风险,这就是正在发生的情况。使用 -
Dsun.zip.disableMemoryMapping=true 将解决该问题,
JDK9 早期访问版本可以解决此问题。
检查原始问题 https://bugs.openjdk.java.net/browse/JDK- 8142508 已在 9 早期访问版本 97 中修复。
Issue is zip/JAR file is being overwritten while in use.
OpenJDK code for ZIP file format is in native C code any entry lookup, creation requires multiple round-trip of expensive jni invocations.
The current native C implementation code uses mmap to map in the central directory table which is a big risk of vm crash when the underlying jar file gets overwritten with new contents while it is still being used by other ZipFile, that is what is happening. Using -
Dsun.zip.disableMemoryMapping=true will solve the problem,
JDK9 early access builds are available that has solution for this.
Check the original issue https://bugs.openjdk.java.net/browse/JDK-8142508 that has been fixed in 9 early access build 97.
除了普通的ol。 JVM 中的错误(升级到最新版本并希望它不会再次发生) - 或使用 JNI 的一些有错误的 3.方库,还有另外 2 个“有趣”的事情可能会导致这种情况。
硬件故障 - RAM 损坏通常是文件系统损坏的一个很好的候选者,而片状驱动器也可能是罪魁祸首。
硬件故障 - RAM
Other than a plain ol. bug in the JVM(upgrade to the latest version and hope it doesn't happen again) - or some buggy 3. party libraries using JNI, there's 2 other "interesting" things that could cause this.
Hardware failure - bad RAM is often a good candidate ot a corrupted filesystem could cause of a flaky drive could be a culprit too.
If you're running on Solaris, you can get SIGBUS errors if somehow the class/jar file was truncated just when the JVM needs to access it in the cases the JVM mmaps the jar/class file.
不知道你的问题解决了没有,因为我也遇到了同样的问题。我只使用 mmap 将 64KB 文件映射到内存中,并使用 memcpy 将数据复制到缓冲区或从缓冲区复制数据。当我使用 JNI 或使用 JNA 时,都会出现同样的错误。我是一名经验丰富的 JNI 程序员多年,并且我在纯 C 程序中完全实现了相同的逻辑,效果非常好。
我认为这是 JDK 的 bug,它捕获了一些 SIG。但我真的没有时间再去挖掘它了。现在我决定放弃这种方法并尝试其他方式来做我想做的事情。
如果您对我这样做的原因感兴趣,我只想在 JNI 中实现一个线程安全内存映射文件。因为在JDK的实现中,位置是ByteBuffer中的全局变量(从FileChannel映射而来)。我只想使用一个 MemoryMappedBuffer 实例来访问我在 C++ 程序中完成的多个线程中的内容。
顺便说一句,我在 Mac OS X 10.10 中使用 JDK 7。
I don't know if you have solved the problem because I encountered exactly the same problem. I only use mmap to map a 64KB file into a memory and use memcpy to copy data to/from the buffer. The same error occurred either when I use JNI or when I use JNA. I'm an experienced JNI programmer for years and I'm exactly implemented the same logic in a pure C program which works pretty well.
I assume it's a JDK's bug which trap some SIGs. But I really don't have time to dig it any more. For now I decided to abandon this approach and try other way to do something I wanna do.
If you're interested in why I'm doing this, I just wanna implement a thread safe memory mapped file in JNI. Because in JDK's implementation, the position is a global variable in ByteBuffer(which is mapped from FileChannel). I just wanna use one MemoryMappedBuffer instance to access the content in multiple threads which I've done in a C++ program.
BTW, I'm using JDK 7 in Mac OS X 10.10.