mirror of
https://github.com/openjdk/jdk.git
synced 2025-08-28 07:14:30 +02:00
8202788: Explicitly reclaim cached thread-local direct buffers at thread exit
Add internal TerminatingThreadLocal and use it to free cached thread-local direct buffers and nio-fs native buffers Reviewed-by: tonyp, alanb
This commit is contained in:
parent
578576f523
commit
6ec2cfcc49
8 changed files with 398 additions and 47 deletions
|
@ -26,6 +26,7 @@
|
|||
package sun.nio.ch;
|
||||
|
||||
import java.io.FileDescriptor;
|
||||
import java.io.IOException;
|
||||
import java.lang.reflect.Constructor;
|
||||
import java.lang.reflect.InvocationTargetException;
|
||||
import java.nio.ByteBuffer;
|
||||
|
@ -35,9 +36,10 @@ import java.security.PrivilegedAction;
|
|||
import java.util.Collection;
|
||||
import java.util.Iterator;
|
||||
import java.util.Set;
|
||||
|
||||
import jdk.internal.misc.TerminatingThreadLocal;
|
||||
import jdk.internal.misc.Unsafe;
|
||||
import sun.security.action.GetPropertyAction;
|
||||
import java.io.IOException;
|
||||
|
||||
public class Util {
|
||||
|
||||
|
@ -50,13 +52,18 @@ public class Util {
|
|||
private static final long MAX_CACHED_BUFFER_SIZE = getMaxCachedBufferSize();
|
||||
|
||||
// Per-thread cache of temporary direct buffers
|
||||
private static ThreadLocal<BufferCache> bufferCache =
|
||||
new ThreadLocal<BufferCache>()
|
||||
{
|
||||
private static ThreadLocal<BufferCache> bufferCache = new TerminatingThreadLocal<>() {
|
||||
@Override
|
||||
protected BufferCache initialValue() {
|
||||
return new BufferCache();
|
||||
}
|
||||
@Override
|
||||
protected void threadTerminated(BufferCache cache) { // will never be null
|
||||
while (!cache.isEmpty()) {
|
||||
ByteBuffer bb = cache.removeFirst();
|
||||
free(bb);
|
||||
}
|
||||
}
|
||||
};
|
||||
|
||||
/**
|
||||
|
|
|
@ -25,6 +25,7 @@
|
|||
|
||||
package sun.nio.fs;
|
||||
|
||||
import jdk.internal.misc.TerminatingThreadLocal;
|
||||
import jdk.internal.misc.Unsafe;
|
||||
|
||||
/**
|
||||
|
@ -37,8 +38,21 @@ class NativeBuffers {
|
|||
private static final Unsafe unsafe = Unsafe.getUnsafe();
|
||||
|
||||
private static final int TEMP_BUF_POOL_SIZE = 3;
|
||||
private static ThreadLocal<NativeBuffer[]> threadLocal =
|
||||
new ThreadLocal<NativeBuffer[]>();
|
||||
private static ThreadLocal<NativeBuffer[]> threadLocal = new TerminatingThreadLocal<>() {
|
||||
@Override
|
||||
protected void threadTerminated(NativeBuffer[] buffers) {
|
||||
// threadLocal may be initialized but with initialValue of null
|
||||
if (buffers != null) {
|
||||
for (int i = 0; i < TEMP_BUF_POOL_SIZE; i++) {
|
||||
NativeBuffer buffer = buffers[i];
|
||||
if (buffer != null) {
|
||||
buffer.free();
|
||||
buffers[i] = null;
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
};
|
||||
|
||||
/**
|
||||
* Allocates a native buffer, of at least the given size, from the heap.
|
||||
|
|
Loading…
Add table
Add a link
Reference in a new issue