Заставить JVM выполнять все операции ввода-вывода без кэширования страниц (например, O_DIRECT)

Я делаю некоторые тесты приложения, написанного на Java. Для экспериментов очень важно, чтобы на результаты не влиял кеш страниц (я использую linux)

Поэтому лучший способ избежать кеша страниц - использовать O_DIRECT при каждом открытии файла. Поэтому я изменил соответствующий код в исходном коде JRE.

Мой подход прекрасно работает для всего, что проходит черезFileOutputStream (например, запись), но это не работает дляFileInputStream (например, чтение).

При добавлении O_DIRECT к открытому вызовуFileInputStream, JVM не может загрузить какие-либо классы:

Error: Could not find or load main class perf.TestDirectIO

Эта ошибка не является проблемой classpath, так как я могу исправить ее, просто используя «не взломанную» 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);

Ответы на вопрос(3)

Ваш ответ на вопрос