diff --git a/src/java.base/share/classes/java/nio/Direct-X-Buffer.java.template b/src/java.base/share/classes/java/nio/Direct-X-Buffer.java.template index f7f1d33228d..e8551bd78c6 100644 --- a/src/java.base/share/classes/java/nio/Direct-X-Buffer.java.template +++ b/src/java.base/share/classes/java/nio/Direct-X-Buffer.java.template @@ -75,31 +75,15 @@ class Direct$Type$Buffer$RW$$BO$ #if[byte] - private static class Deallocator - implements Runnable - { - - private long address; - private long size; - private int capacity; - - private Deallocator(long address, long size, int capacity) { - assert (address != 0); - this.address = address; - this.size = size; - this.capacity = capacity; + private record Deallocator(long address, long size, int capacity) implements Runnable { + private Deallocator { + assert address != 0; } public void run() { - if (address == 0) { - // Paranoia - return; - } UNSAFE.freeMemory(address); - address = 0; Bits.unreserveMemory(size, capacity); } - } private final Cleaner cleaner; diff --git a/src/java.base/share/classes/java/nio/MappedByteBuffer.java b/src/java.base/share/classes/java/nio/MappedByteBuffer.java index be7a7988ec3..8b51d602f28 100644 --- a/src/java.base/share/classes/java/nio/MappedByteBuffer.java +++ b/src/java.base/share/classes/java/nio/MappedByteBuffer.java @@ -116,28 +116,33 @@ public abstract sealed class MappedByteBuffer } UnmapperProxy unmapper() { - return fd != null ? - new UnmapperProxy() { - @Override - public long address() { - return address; - } + return fd == null + ? null + : new UnmapperProxy() { - @Override - public FileDescriptor fileDescriptor() { - return fd; - } + // Ensure safe publication as MappedByteBuffer.this.address is not final + private final long addr = address; - @Override - public boolean isSync() { - return isSync; - } + @Override + public long address() { + return addr; + } - @Override - public void unmap() { - Unsafe.getUnsafe().invokeCleaner(MappedByteBuffer.this); - } - } : null; + @Override + public FileDescriptor fileDescriptor() { + return fd; + } + + @Override + public boolean isSync() { + return isSync; + } + + @Override + public void unmap() { + Unsafe.getUnsafe().invokeCleaner(MappedByteBuffer.this); + } + }; } /** diff --git a/src/java.base/share/classes/sun/nio/ch/FileChannelImpl.java b/src/java.base/share/classes/sun/nio/ch/FileChannelImpl.java index 04a22102b26..0cbcdf7c94a 100644 --- a/src/java.base/share/classes/sun/nio/ch/FileChannelImpl.java +++ b/src/java.base/share/classes/sun/nio/ch/FileChannelImpl.java @@ -1154,10 +1154,10 @@ public class FileChannelImpl // -- Memory-mapped buffers -- - private abstract static class Unmapper + private sealed abstract static class Unmapper implements Runnable, UnmapperProxy { - private volatile long address; + private final long address; protected final long size; protected final long cap; private final FileDescriptor fd; @@ -1194,10 +1194,7 @@ public class FileChannelImpl } public void unmap() { - if (address == 0) - return; nd.unmap(address, size); - address = 0; // if this mapping has a valid file descriptor then we close it if (fd.valid()) { @@ -1214,7 +1211,7 @@ public class FileChannelImpl protected abstract void decrementStats(); } - private static class DefaultUnmapper extends Unmapper { + private static final class DefaultUnmapper extends Unmapper { // keep track of non-sync mapped buffer usage static volatile int count; @@ -1247,7 +1244,7 @@ public class FileChannelImpl } } - private static class SyncUnmapper extends Unmapper { + private static final class SyncUnmapper extends Unmapper { // keep track of mapped buffer usage static volatile int count;