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      */

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      */

91     public static int releaseBuffers() {
92         if (_bufferRecyclerTracker != null) {
93             return _bufferRecyclerTracker.releaseBuffers();
94         }
95         return -1;
96     }
97 }
98