From ea0a8cdc7770ff685df7e8fd0aff15dc0e43f5ce Mon Sep 17 00:00:00 2001 From: Prashanth Joseph Babu Date: Tue, 26 Jul 2022 09:33:49 +0530 Subject: [PATCH] fix memory mapped files leak --- .../bigqueue/page/MappedPageImpl.java | 59 ++++++++----------- 1 file changed, 26 insertions(+), 33 deletions(-) diff --git a/src/main/java/com/leansoft/bigqueue/page/MappedPageImpl.java b/src/main/java/com/leansoft/bigqueue/page/MappedPageImpl.java index 6fb1249..a8ece7e 100644 --- a/src/main/java/com/leansoft/bigqueue/page/MappedPageImpl.java +++ b/src/main/java/com/leansoft/bigqueue/page/MappedPageImpl.java @@ -1,8 +1,12 @@ package com.leansoft.bigqueue.page; +import org.slf4j.Logger; +import org.slf4j.LoggerFactory; +import sun.misc.Unsafe; + import java.io.Closeable; import java.io.IOException; -import java.lang.reflect.Method; +import java.lang.reflect.Field; import java.nio.ByteBuffer; import java.nio.MappedByteBuffer; @@ -86,40 +90,29 @@ private static void unmap(MappedByteBuffer buffer) * Helper class allowing to clean direct buffers. */ private static class Cleaner { - public static final boolean CLEAN_SUPPORTED; - private static final Method directBufferCleaner; - private static final Method directBufferCleanerClean; + private static Unsafe unsafe; - static { - Method directBufferCleanerX = null; - Method directBufferCleanerCleanX = null; - boolean v; - try { - directBufferCleanerX = Class.forName("java.nio.DirectByteBuffer").getMethod("cleaner"); - directBufferCleanerX.setAccessible(true); - directBufferCleanerCleanX = Class.forName("sun.misc.Cleaner").getMethod("clean"); - directBufferCleanerCleanX.setAccessible(true); - v = true; - } catch (Exception e) { - v = false; - } - CLEAN_SUPPORTED = v; - directBufferCleaner = directBufferCleanerX; - directBufferCleanerClean = directBufferCleanerCleanX; - } + static { + try { + Field f = Unsafe.class.getDeclaredField("theUnsafe"); + f.setAccessible(true); + unsafe = (Unsafe) f.get(null); + } catch (Exception e) { + logger.warn("Unsafe Not support {}", e.getMessage(), e); + } + } - public static void clean(ByteBuffer buffer) { - if (buffer == null) return; - if (CLEAN_SUPPORTED && buffer.isDirect()) { - try { - Object cleaner = directBufferCleaner.invoke(buffer); - directBufferCleanerClean.invoke(cleaner); - } catch (Exception e) { - // silently ignore exception - } - } - } - } + public static void clean(ByteBuffer buffer) { + if (buffer == null) return; + if (buffer.isDirect()) { + if (unsafe != null) { + unsafe.invokeCleaner(buffer); + } else { + logger.warn("Unable to clean bytebuffer"); + } + } + } + } private static class ThreadLocalByteBuffer extends ThreadLocal { private ByteBuffer _src;