Clean up Direct Memory Region Files Fix for different Java versions
Java 9+ doesn't allow using the exposed cleanup method, but added a new method on Unsafe to do it. So have to detect java version and use the appropriate strategy.
This commit is contained in:
parent
55e3501967
commit
a4ed58a9ab
1 changed files with 56 additions and 4 deletions
|
@ -1,4 +1,4 @@
|
||||||
From b649a81d4edeb173e725b72ad931a7f0a81b6714 Mon Sep 17 00:00:00 2001
|
From 8fdbc0b6bb68ba8e6f6ce8035c9936e3922808f0 Mon Sep 17 00:00:00 2001
|
||||||
From: Aikar <aikar@aikar.co>
|
From: Aikar <aikar@aikar.co>
|
||||||
Date: Mon, 4 May 2020 00:38:13 -0400
|
Date: Mon, 4 May 2020 00:38:13 -0400
|
||||||
Subject: [PATCH] Cleanup Region Files Direct Memory on close
|
Subject: [PATCH] Cleanup Region Files Direct Memory on close
|
||||||
|
@ -10,7 +10,7 @@ Finalizers have no guarantee on when they will be ran, and since this is
|
||||||
old generation memory, it might be a while before its called.
|
old generation memory, it might be a while before its called.
|
||||||
|
|
||||||
diff --git a/src/main/java/net/minecraft/server/RegionFile.java b/src/main/java/net/minecraft/server/RegionFile.java
|
diff --git a/src/main/java/net/minecraft/server/RegionFile.java b/src/main/java/net/minecraft/server/RegionFile.java
|
||||||
index df728e2c0a..c565307a58 100644
|
index df728e2c0a..20927d55c6 100644
|
||||||
--- a/src/main/java/net/minecraft/server/RegionFile.java
|
--- a/src/main/java/net/minecraft/server/RegionFile.java
|
||||||
+++ b/src/main/java/net/minecraft/server/RegionFile.java
|
+++ b/src/main/java/net/minecraft/server/RegionFile.java
|
||||||
@@ -30,7 +30,7 @@ public class RegionFile implements AutoCloseable {
|
@@ -30,7 +30,7 @@ public class RegionFile implements AutoCloseable {
|
||||||
|
@ -22,14 +22,66 @@ index df728e2c0a..c565307a58 100644
|
||||||
private final IntBuffer g;
|
private final IntBuffer g;
|
||||||
private final IntBuffer h;
|
private final IntBuffer h;
|
||||||
private final RegionFileBitSet freeSectors;
|
private final RegionFileBitSet freeSectors;
|
||||||
@@ -403,6 +403,7 @@ public class RegionFile implements AutoCloseable {
|
@@ -403,10 +403,59 @@ public class RegionFile implements AutoCloseable {
|
||||||
}
|
}
|
||||||
} finally { // Paper start - Prevent regionfiles from being closed during use
|
} finally { // Paper start - Prevent regionfiles from being closed during use
|
||||||
this.fileLock.unlock();
|
this.fileLock.unlock();
|
||||||
+ if (getFileBuffer() instanceof sun.nio.ch.DirectBuffer) ((sun.nio.ch.DirectBuffer) getFileBuffer()).cleaner().clean(); // Paper - clean up direct buffers on close
|
+ if (getFileBuffer().isDirect()) cleanDirectByteBuffer(getFileBuffer()); // Paper - clean up direct buffers on close
|
||||||
}
|
}
|
||||||
} // Paper end
|
} // Paper end
|
||||||
|
|
||||||
|
}
|
||||||
|
+ // Paper start
|
||||||
|
+ private static int getVersion() {
|
||||||
|
+ String version = System.getProperty("java.version");
|
||||||
|
+ if(version.startsWith("1.")) {
|
||||||
|
+ version = version.substring(2, 3);
|
||||||
|
+ } else {
|
||||||
|
+ int dot = version.indexOf(".");
|
||||||
|
+ if(dot != -1) { version = version.substring(0, dot); }
|
||||||
|
+ } return Integer.parseInt(version);
|
||||||
|
+ }
|
||||||
|
+ static java.lang.reflect.Method unsafeClean;
|
||||||
|
+ static sun.misc.Unsafe unsafe = com.destroystokyo.paper.utils.UnsafeUtils.getUnsafe();
|
||||||
|
+ static java.util.function.Consumer<ByteBuffer> cleaner;
|
||||||
|
+ static {
|
||||||
|
+ try {
|
||||||
|
+ if (unsafe != null) {
|
||||||
|
+ unsafeClean = unsafe.getClass().getMethod("invokeCleaner", ByteBuffer.class);
|
||||||
|
+ if (unsafeClean != null) {
|
||||||
|
+ cleaner = (buf) -> {
|
||||||
|
+ try {
|
||||||
|
+ unsafeClean.invoke(unsafe, buf);
|
||||||
|
+ } catch (Exception ex) {
|
||||||
|
+ com.destroystokyo.paper.util.SneakyThrow.sneaky(ex);
|
||||||
|
+ }
|
||||||
|
+ };
|
||||||
|
+ LOGGER.info("[RegionFile] Using Java 9+ invokeCleaner DirectByteBuffer cleanup method");
|
||||||
|
+ }
|
||||||
|
+ }
|
||||||
|
+ } catch (java.lang.NoSuchMethodException e) {}
|
||||||
|
+ if (cleaner == null && getVersion() <= 8) {
|
||||||
|
+ cleaner = (buf) -> {
|
||||||
|
+ ((sun.nio.ch.DirectBuffer) buf).cleaner().clean();
|
||||||
|
+ };
|
||||||
|
+ LOGGER.info("[RegionFile] Using Java 8 DirectByteBuffer cleanup method");
|
||||||
|
+ }
|
||||||
|
+ }
|
||||||
|
+ public static void cleanDirectByteBuffer(ByteBuffer toBeDestroyed) {
|
||||||
|
+ try {
|
||||||
|
+ if (cleaner != null) {
|
||||||
|
+ cleaner.accept(toBeDestroyed);
|
||||||
|
+ }
|
||||||
|
+ } catch (Exception ex) {
|
||||||
|
+ LOGGER.warn("Failed automatically cleaning DirectByteBuffer");
|
||||||
|
+ ex.printStackTrace();
|
||||||
|
+ cleaner = null;
|
||||||
|
+ }
|
||||||
|
+ }
|
||||||
|
+ // Paper end
|
||||||
|
|
||||||
|
private void c() throws IOException {
|
||||||
|
int i = (int) this.dataFile.size();
|
||||||
--
|
--
|
||||||
2.26.2
|
2.26.2
|
||||||
|
|
||||||
|
|
Loading…
Reference in a new issue