您的位置:首页 > 其它

热替换jar包导致JVM崩溃(crash)

2017-03-17 18:10 381 查看
情景

在一次项目升级过程中,需要替换一个jar包,已经有进程用这个jar包启动运行了。

操作

当没有终止这些进程的情况下,热替换该jar包

现象

替换jar包之后,在运行的进程全部消失了,打印出jvm crash的日志。

原因

查找相关资料后发现是因为java读取jar包时,为了提高性能,默认使用了mmap,也就是文件到内存的映射,使用mmap是调用的本地方法,当jar包替换后如果又触发类加载就有可能导致异常,而jvm没法控制本地方法,从而导致jvm crash。

解决方案

使用该参数关闭mmap

-Dsun.zip.disableMemoryMapping=true


但是该参数只能保证jvm不crash,但是热替换jar包后,当有些类需要加载的时候还是可能导致异常。所以该方法只是不让jvm崩溃而已,想要真正解决的话就不要在进程在执行的时候替换jar包。

总结

其实不仅仅时热替换jar包,如果在zip包读的时候更改该zip包,也有可能导致jvm crash。应该时jdk1.9之后会把mmap部分的代码用java实现来解决jvm crash的问题。

最后附上oracle官网上的解释:

Disabling 
mmap
 Usage (on Solaris or Linux)

This release includes a new system property
4000
sun.zip.disableMemoryMapping
, which allows the user to disable the 
mmap
 usage in Sun's 
java.util.zip.Zipfile
 implementation
(on Solaris and Linux platforms). Solaris or Linux applications that use 
java.util.zip.ZipFile
 may experience a 
SIGBUS
 VM crash if the application accidentally overwrites any zip or jar files that are still being
used by the same Java runtime. Although this is a programming error of the offending application, this system property provides a solution to avoid the VM crash. With the property set to true (
-Dsun.zip.disableMemoryMapping=true
, or simply 
-Dsun.zip.disableMemoryMapping
)
the Sun JDK/JRE runtime disables the 
mmap
 usage and the VM crash that might otherwise occur by overwriting the jar or zip file can be avoided.

详情见:http://www.oracle.com/technetwork/java/javase/documentation/overview-156328.html#6u21-rev-b09
内容来自用户分享和网络整理,不保证内容的准确性,如有侵权内容,可联系管理员处理 点击这里给我发消息
标签: