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