Wymuś JVM na wykonanie wszystkich operacji we / wy bez pamięci podręcznej stron (np. O_DIRECT)

Robię kilka testów aplikacji napisanej w Javie. Bardzo ważne dla eksperymentów, na które wyniki nie mają wpływu pamięć podręczna stron (używam Linuksa)

Najlepszym sposobem uniknięcia pamięci podręcznej strony jest użycie O_DIRECT przy każdym otwarciu pliku. Dlatego zmieniłem odpowiedni kod w kodzie źródłowym jre.

Moje podejście działa idealnie na wszystko, co przechodzi przezFileOutputStream (np. pisanie), ale nie działaFileInputStream (np. czytanie).

Podczas dodawania O_DIRECT do otwartego wywołania zFileInputStreamJVM nie może załadować żadnych klas:

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

Ten błąd nie jest problemem klasy classpath, ponieważ mogę go naprawić, używając „niehackowanej” maszyny JVM.

Wygląda więc na to, że problem dotyczy otwierania plików.

Jestem bardzo zadowolony z wszelkich porad, jak rozwiązać ten problem.

Jeśli ktoś kiedykolwiek chce zrobić coś podobnego, jaudokumentowałem cały hack na moim blogu.

Jako odniesienie, są to zmiany kodu JVM, które zrobiłem:

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
 }

Ta zmiana działa: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));
 }

Zmieniłem również punkt dostępu hotspot, aby zapewnić wyrównanie pamięci (to jest wymóg dla 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);

questionAnswers(3)

yourAnswerToTheQuestion