1 package com.fasterxml.jackson.core.util; 2 3 import java.lang.ref.SoftReference; 4 5 /** 6 * Helper entity used to control access to simple buffer recyling scheme used for 7 * some encoding, decoding tasks. 8 * 9 * @see BufferRecycler 10 * 11 * @since 2.9.2 12 */ 13 public class BufferRecyclers 14 { 15 /** 16 * System property that is checked to see if recycled buffers (see {@link BufferRecycler}) 17 * should be tracked, for purpose of forcing release of all such buffers, typically 18 * during major classloading. 19 * 20 * @since 2.9.6 21 */ 22 public final static String SYSTEM_PROPERTY_TRACK_REUSABLE_BUFFERS 23 = "com.fasterxml.jackson.core.util.BufferRecyclers.trackReusableBuffers"; 24 25 /* 26 /********************************************************** 27 /* Life-cycle 28 /********************************************************** 29 */ 30 31 /** 32 * Flag that indicates whether {@link BufferRecycler} instances should be tracked. 33 */ 34 private final static ThreadLocalBufferManager _bufferRecyclerTracker; 35 static { 36 boolean trackReusableBuffers = false; 37 try { 38 trackReusableBuffers = "true".equals(System.getProperty(SYSTEM_PROPERTY_TRACK_REUSABLE_BUFFERS)); 39 } catch (SecurityException e) { } 40 41 _bufferRecyclerTracker = trackReusableBuffers ? ThreadLocalBufferManager.instance() : null; 42 } 43 44 /* 45 /********************************************************** 46 /* BufferRecyclers for parsers, generators 47 /********************************************************** 48 */ 49 50 /** 51 * This <code>ThreadLocal</code> contains a {@link java.lang.ref.SoftReference} 52 * to a {@link BufferRecycler} used to provide a low-cost 53 * buffer recycling between reader and writer instances. 54 */ 55 final protected static ThreadLocal<SoftReference<BufferRecycler>> _recyclerRef 56 = new ThreadLocal<SoftReference<BufferRecycler>>(); 57 58 /** 59 * Main accessor to call for accessing possibly recycled {@link BufferRecycler} instance. 60 */ getBufferRecycler()61 public static BufferRecycler getBufferRecycler() 62 { 63 SoftReference<BufferRecycler> ref = _recyclerRef.get(); 64 BufferRecycler br = (ref == null) ? null : ref.get(); 65 66 if (br == null) { 67 br = new BufferRecycler(); 68 if (_bufferRecyclerTracker != null) { 69 ref = _bufferRecyclerTracker.wrapAndTrack(br); 70 } else { 71 ref = new SoftReference<BufferRecycler>(br); 72 } 73 _recyclerRef.set(ref); 74 } 75 return br; 76 } 77 78 /** 79 * Specialized method that will release all recycled {@link BufferRecycler} if 80 * (and only if) recycler tracking has been enabled 81 * (see {@link #SYSTEM_PROPERTY_TRACK_REUSABLE_BUFFERS}). 82 * This method is usually called on shutdown of the container like Application Server 83 * to ensure that no references are reachable via {@link ThreadLocal}s as this may cause 84 * unintentional retention of sizable amounts of memory. It may also be called regularly 85 * if GC for some reason does not clear up {@link SoftReference}s aggressively enough. 86 * 87 * @return Number of buffers released, if tracking enabled (zero or more); -1 if tracking not enabled. 88 * 89 * @since 2.9.6 90 */ releaseBuffers()91 public static int releaseBuffers() { 92 if (_bufferRecyclerTracker != null) { 93 return _bufferRecyclerTracker.releaseBuffers(); 94 } 95 return -1; 96 } 97 } 98