/** * Specialized method that will release all recycled {@link BufferRecycler} if * (and only if) recycler tracking has been enabled * (see {@link #SYSTEM_PROPERTY_TRACK_REUSABLE_BUFFERS}). * This method is usually called on shutdown of the container like Application Server * to ensure that no references are reachable via {@link ThreadLocal}s as this may cause * unintentional retention of sizable amounts of memory. It may also be called regularly * if GC for some reason does not clear up {@link SoftReference}s aggressively enough. * * @return Number of buffers released, if tracking enabled (zero or more); -1 if tracking not enabled. * * @since 2.9.6 */ public static int releaseBuffers() { if (_bufferRecyclerTracker != null) { return _bufferRecyclerTracker.releaseBuffers(); } return -1; }
public SoftReference<BufferRecycler> wrapAndTrack(BufferRecycler br) { SoftReference<BufferRecycler> newRef; newRef = new SoftReference<BufferRecycler>(br, _refQueue); // also retain softRef to br in a set to be able to release it on shutdown _trackedRecyclers.put(newRef, true); // gc may have cleared one or more SoftRefs, clean them up to avoid a memleak removeSoftRefsClearedByGc(); return newRef; }
/** * Main accessor to call for accessing possibly recycled {@link BufferRecycler} instance. */ public static BufferRecycler getBufferRecycler() { SoftReference<BufferRecycler> ref = _recyclerRef.get(); BufferRecycler br = (ref == null) ? null : ref.get(); if (br == null) { br = new BufferRecycler(); if (_bufferRecyclerTracker != null) { ref = _bufferRecyclerTracker.wrapAndTrack(br); } else { ref = new SoftReference<BufferRecycler>(br); } _recyclerRef.set(ref); } return br; }
public SoftReference<BufferRecycler> wrapAndTrack(BufferRecycler br) { SoftReference<BufferRecycler> newRef; newRef = new SoftReference<BufferRecycler>(br, _refQueue); // also retain softRef to br in a set to be able to release it on shutdown _trackedRecyclers.put(newRef, true); // gc may have cleared one or more SoftRefs, clean them up to avoid a memleak removeSoftRefsClearedByGc(); return newRef; }
/** * Main accessor to call for accessing possibly recycled {@link BufferRecycler} instance. */ public static BufferRecycler getBufferRecycler() { SoftReference<BufferRecycler> ref = _recyclerRef.get(); BufferRecycler br = (ref == null) ? null : ref.get(); if (br == null) { br = new BufferRecycler(); if (_bufferRecyclerTracker != null) { ref = _bufferRecyclerTracker.wrapAndTrack(br); } else { ref = new SoftReference<BufferRecycler>(br); } _recyclerRef.set(ref); } return br; }
/** * Specialized method that will release all recycled {@link BufferRecycler} if * (and only if) recycler tracking has been enabled * (see {@link #SYSTEM_PROPERTY_TRACK_REUSABLE_BUFFERS}). * This method is usually called on shutdown of the container like Application Server * to ensure that no references are reachable via {@link ThreadLocal}s as this may cause * unintentional retention of sizable amounts of memory. It may also be called regularly * if GC for some reason does not clear up {@link SoftReference}s aggressively enough. * * @return Number of buffers released, if tracking enabled (zero or more); -1 if tracking not enabled. * * @since 2.9.6 */ public static int releaseBuffers() { if (_bufferRecyclerTracker != null) { return _bufferRecyclerTracker.releaseBuffers(); } return -1; }
/** * Releases the buffers retained in ThreadLocals. To be called for instance on shutdown event of applications which make use of * an environment like an appserver which stays alive and uses a thread pool that causes ThreadLocals created by the * application to survive much longer than the application itself. * It will clear all bufRecyclers from the SoftRefs and release all SoftRefs itself from our set. */ public int releaseBuffers() { synchronized (RELEASE_LOCK) { int count = 0; // does this need to be in sync block too? Looping over Map definitely has to but... removeSoftRefsClearedByGc(); // make sure the refQueue is empty for (SoftReference<BufferRecycler> ref : _trackedRecyclers.keySet()) { ref.clear(); // possibly already cleared by gc, nothing happens in that case ++count; } _trackedRecyclers.clear(); //release cleared SoftRefs return count; } }
/** * Main accessor to call for accessing possibly recycled {@link BufferRecycler} instance. */ public static BufferRecycler getBufferRecycler() { SoftReference<BufferRecycler> ref = _recyclerRef.get(); BufferRecycler br = (ref == null) ? null : ref.get(); if (br == null) { br = new BufferRecycler(); if (_bufferRecyclerTracker != null) { ref = _bufferRecyclerTracker.wrapAndTrack(br); } else { ref = new SoftReference<BufferRecycler>(br); } _recyclerRef.set(ref); } return br; }
/** * Specialized method that will release all recycled {@link BufferRecycler} if * (and only if) recycler tracking has been enabled * (see {@link #SYSTEM_PROPERTY_TRACK_REUSABLE_BUFFERS}). * This method is usually called on shutdown of the container like Application Server * to ensure that no references are reachable via {@link ThreadLocal}s as this may cause * unintentional retention of sizable amounts of memory. It may also be called regularly * if GC for some reason does not clear up {@link SoftReference}s aggressively enough. * * @return Number of buffers released, if tracking enabled (zero or more); -1 if tracking not enabled. * * @since 2.9.6 */ public static int releaseBuffers() { if (_bufferRecyclerTracker != null) { return _bufferRecyclerTracker.releaseBuffers(); } return -1; }
/** * Releases the buffers retained in ThreadLocals. To be called for instance on shutdown event of applications which make use of * an environment like an appserver which stays alive and uses a thread pool that causes ThreadLocals created by the * application to survive much longer than the application itself. * It will clear all bufRecyclers from the SoftRefs and release all SoftRefs itself from our set. */ public int releaseBuffers() { synchronized (RELEASE_LOCK) { int count = 0; // does this need to be in sync block too? Looping over Map definitely has to but... removeSoftRefsClearedByGc(); // make sure the refQueue is empty for (SoftReference<BufferRecycler> ref : _trackedRecyclers.keySet()) { ref.clear(); // possibly already cleared by gc, nothing happens in that case ++count; } _trackedRecyclers.clear(); //release cleared SoftRefs return count; } }
public SoftReference<BufferRecycler> wrapAndTrack(BufferRecycler br) { SoftReference<BufferRecycler> newRef; newRef = new SoftReference<BufferRecycler>(br, _refQueue); // also retain softRef to br in a set to be able to release it on shutdown _trackedRecyclers.put(newRef, true); // gc may have cleared one or more SoftRefs, clean them up to avoid a memleak removeSoftRefsClearedByGc(); return newRef; }
/** * Releases the buffers retained in ThreadLocals. To be called for instance on shutdown event of applications which make use of * an environment like an appserver which stays alive and uses a thread pool that causes ThreadLocals created by the * application to survive much longer than the application itself. * It will clear all bufRecyclers from the SoftRefs and release all SoftRefs itself from our set. */ public int releaseBuffers() { synchronized (RELEASE_LOCK) { int count = 0; // does this need to be in sync block too? Looping over Map definitely has to but... removeSoftRefsClearedByGc(); // make sure the refQueue is empty for (SoftReference<BufferRecycler> ref : _trackedRecyclers.keySet()) { ref.clear(); // possibly already cleared by gc, nothing happens in that case ++count; } _trackedRecyclers.clear(); //release cleared SoftRefs return count; } }