私はJavaで書かれたアプリケーションのいくつかのベンチマークを行っています。結果がページキャッシュの影響を受けないことが実験にとって非常に重要です(私はLinuxを使用しています)
したがって、ページキャッシュを回避する最善の方法は、ファイルが開かれるたびにO_DIRECTを使用することです。そのため、jreのソースコードのそれぞれのコードを変更しました。
私のアプローチは、(たとえば書き込み)を通過するすべてのものに対して完全に機能しますが、 (たとえば読み取り)FileOutputStream
に対しては機能しません。FileInputStream
のopen-callにO_DIRECTを追加するとFileInputStream
、JVMはクラスをロードできません。
Error: Could not find or load main class perf.TestDirectIO
「ハッキングされていない」JVMを使用するだけで修正できるため、このエラーはクラスパスの問題ではありません。
したがって、ファイルを開く際に問題があるようです。
問題を解決する方法についてのアドバイスをとてもうれしく思います。
誰かが似たようなことをしたい場合は、ハック全体をブログに記録しました。
参考までに、これらは私が行ったJVMコードの変更です。
jdk/src/share/native/java/io/FileInputStream.c
:
@@ -58,7 +60,8 @@
JNIEXPORT void JNICALL
Java_java_io_FileInputStream_open(JNIEnv *env, jobject this, jstring path) {
- fileOpen(env, this, path, fis_fd, O_RDONLY);
+ fileOpen(env, this, path, fis_fd, O_RDONLY | O_DIRECT); // this is the change that causes all the problems
}
この変更は機能します
jdk/src/solaris/native/java/io/FileOutputStream_md.c
::
@@ -55,8 +55,10 @@
JNIEXPORT void JNICALL
Java_java_io_FileOutputStream_open(JNIEnv *env, jobject this,
jstring path, jboolean append) {
fileOpen(env, this, path, fos_fd,
- O_WRONLY | O_CREAT | (append ? O_APPEND : O_TRUNC));
+ O_WRONLY | O_DIRECT | O_CREAT | (append ? O_APPEND : O_TRUNC));
}
また、ホットスポットjreを変更して、メモリが調整されていることを確認しました(これは、O_DIRECTの要件です)
hotspot/src/share/vm/runtime/os.cpp
。
+# include <mm_malloc.h>
...
- u_char* ptr = (u_char*)::malloc(size + space_before + space_after);
+ u_char* ptr = (u_char*)::_mm_malloc(size + space_before + space_after,512);