https://blogs.oracle.com/poonam/entry/crashes_in_zip_getentry
先日、以下のようなスタックトレース付きで、アプリケーションクラッシュに関する数多くの報告が、様々なお客様や製品グループから寄せられました。
ほとんどの場合、JVMインスタンス実行中にアクセスしているjarファイルを変更、上書きした際にZIP_GetEntryにてクラッシュが発生しています。パフォーマンスの理由により、HotSpot JVMのメモリはmmapを使い各Jarファイルのセントラルディレクトリ構造にマップします。こうすることで、Jarファイルからエントリを読み取る必要がある都度セントラルディレクトリ構造データをディスクから読み取ることを避けています。Jarファイルをディスク上で変更、上書きする場合、以前に読み取ったJVMのデータのコピーがディスク上のJarファイルと一致しなくなり、変更されたJarファイルからエントリを読み取り、ロードしようとするとアプリケーションクラッシュが発生することがあります。Stack: [0xb0c00000,0xb0c80000], sp=0xb0c7c890, free space=498k Native frames: (J=compiled Java code, j=interpreted, Vv=VM code, C=native code) C [libc_psr.so.1+0x700] memcpy+0x2f8 C [libzip.so+0xd19c] C [libzip.so+0x2380] ZIP_GetEntry+0xe4 C [libzip.so+0x2800] Java_java_util_zip_ZipFile_getEntry+0xc4 j java.util.zip.ZipFile.getEntry(JLjava/lang/String;Z)J+0 j java.util.zip.ZipFile.getEntry(JLjava/lang/String;Z)J+0 j java.util.zip.ZipFile.getEntry(Ljava/lang/String;)Ljava/util/zip/ZipEntry;+31 j java.util.jar.JarFile.getEntry(Ljava/lang/String;)Ljava/util/zip/ZipEntry;+2 j java.util.jar.JarFile.getJarEntry(Ljava/lang/String;)Ljava/util/jar/JarEntry;+2
Java 1.6.0_23以後では、プロパティを使ってJarファイルのセントラルディレクトリ構造メモリマッピングのマッピングを抑止することができます。
このプロパティを有効にすると、JVMはJarファイルのエントリを読み出す都度ディスク上のJarファイルからセントラルディレクトリ構造を読み取る必要があるため、アプリケーションのパフォーマンスに影響することにご注意ください。そのため、JVMがJarファイルのイメージをロードしている間は、Jarファイルを変更したり上書きしたりしないようにすることがベストです。-Dsun.zip.disableMemoryMapping=true
Java 9では、このZIPクラッシュを以下の機能強化で解決しました。
JDK-8142508: To bring j.u.z.ZipFile's native implementation to Java to remove the expensive jni cost and mmap crash riskこの変更に対するコード・レビューのスレッドは以下からどうぞ。
https://bugs.openjdk.java.net/browse/JDK-8142508
RFR: JDK-8142508: To bring j.u.z.ZipFile's native implementation to Java to remove the expensive jni cost and mmap crash riskこの機能強化はmmapを使うZIPファイルのネイティブ実装をJava実装に置き換え、上述のアプリケーションクラッシュのリスクを除去しています。
http://mail.openjdk.java.net/pipermail/core-libs-dev/2015-November/036495.html
0 件のコメント:
コメントを投稿