Home / Class/ DefaultResourceLeak Class — netty Architecture

DefaultResourceLeak Class — netty Architecture

Architecture documentation for the DefaultResourceLeak class in ResourceLeakDetector.java from the netty codebase.

Entity Profile

Dependency Diagram

graph TD
  0693d07b_5a78_e1d2_0694_de182ea7e0a6["DefaultResourceLeak"]
  d32ce738_76fd_52e1_72e6_97f959369f2a["ResourceLeakDetector.java"]
  0693d07b_5a78_e1d2_0694_de182ea7e0a6 -->|defined in| d32ce738_76fd_52e1_72e6_97f959369f2a
  d4e09515_5a67_39fd_920d_8c1d27f84d77["DefaultResourceLeak()"]
  0693d07b_5a78_e1d2_0694_de182ea7e0a6 -->|method| d4e09515_5a67_39fd_920d_8c1d27f84d77
  2b39451e_97cf_55c0_71d4_1406fc75aa6c["record()"]
  0693d07b_5a78_e1d2_0694_de182ea7e0a6 -->|method| 2b39451e_97cf_55c0_71d4_1406fc75aa6c
  8f406d36_7022_4ea4_114b_0a77991c8aff["record0()"]
  0693d07b_5a78_e1d2_0694_de182ea7e0a6 -->|method| 8f406d36_7022_4ea4_114b_0a77991c8aff
  836a7c81_609c_0085_1045_b69a2142ec31["dispose()"]
  0693d07b_5a78_e1d2_0694_de182ea7e0a6 -->|method| 836a7c81_609c_0085_1045_b69a2142ec31
  19933ffe_052a_9a22_2cf8_d1cc46f96c9a["close()"]
  0693d07b_5a78_e1d2_0694_de182ea7e0a6 -->|method| 19933ffe_052a_9a22_2cf8_d1cc46f96c9a
  b8a1d999_7919_a586_f28b_1b2513c39fe3["reachabilityFence0()"]
  0693d07b_5a78_e1d2_0694_de182ea7e0a6 -->|method| b8a1d999_7919_a586_f28b_1b2513c39fe3
  03052503_d987_b000_6353_5dafed226112["Throwable()"]
  0693d07b_5a78_e1d2_0694_de182ea7e0a6 -->|method| 03052503_d987_b000_6353_5dafed226112
  befe889d_9338_fff8_1c16_76b15e3bd1f6["String()"]
  0693d07b_5a78_e1d2_0694_de182ea7e0a6 -->|method| befe889d_9338_fff8_1c16_76b15e3bd1f6

Relationship Graph

Source Code

common/src/main/java/io/netty/util/ResourceLeakDetector.java lines 399–639

    @SuppressWarnings("deprecation")
    private static final class DefaultResourceLeak<T>
            extends WeakReference<Object> implements ResourceLeakTracker<T>, ResourceLeak {

        @SuppressWarnings({"unchecked", "rawtypes"}) // generics and updaters do not mix.
        private static final AtomicReferenceFieldUpdater<DefaultResourceLeak<?>, TraceRecord> headUpdater =
                (AtomicReferenceFieldUpdater)
                        AtomicReferenceFieldUpdater.newUpdater(DefaultResourceLeak.class, TraceRecord.class, "head");

        @SuppressWarnings({"unchecked", "rawtypes"}) // generics and updaters do not mix.
        private static final AtomicIntegerFieldUpdater<DefaultResourceLeak<?>> droppedRecordsUpdater =
                (AtomicIntegerFieldUpdater)
                        AtomicIntegerFieldUpdater.newUpdater(DefaultResourceLeak.class, "droppedRecords");

        @SuppressWarnings("unused")
        private volatile TraceRecord head;
        @SuppressWarnings("unused")
        private volatile int droppedRecords;

        private final Set<DefaultResourceLeak<?>> allLeaks;
        private final int trackedHash;

        DefaultResourceLeak(
                Object referent,
                ReferenceQueue<Object> refQueue,
                Set<DefaultResourceLeak<?>> allLeaks,
                Object initialHint) {
            super(referent, refQueue);

            assert referent != null;

            this.allLeaks = allLeaks;

            // Store the hash of the tracked object to later assert it in the close(...) method.
            // It's important that we not store a reference to the referent as this would disallow it from
            // be collected via the WeakReference.
            trackedHash = System.identityHashCode(referent);
            allLeaks.add(this);
            // Create a new Record so we always have the creation stacktrace included.
            headUpdater.set(this, initialHint == null ?
                    new TraceRecord(TraceRecord.BOTTOM) : new TraceRecord(TraceRecord.BOTTOM, initialHint));
        }

        @Override
        public void record() {
            record0(null);
        }

        @Override
        public void record(Object hint) {
            record0(hint);
        }

        /**
         * This method works by exponentially backing off as more records are present in the stack. Each record has a
         * 1 / 2^n chance of dropping the top most record and replacing it with itself. This has a number of convenient
         * properties:
         *
         * <ol>
         * <li>  The current record is always recorded. This is due to the compare and swap dropping the top most
         *       record, rather than the to-be-pushed record.
         * <li>  The very last access will always be recorded. This comes as a property of 1.
         * <li>  It is possible to retain more records than the target, based upon the probability distribution.
         * <li>  It is easy to keep a precise record of the number of elements in the stack, since each element has to
         *     know how tall the stack is.
         * </ol>
         *
         * In this particular implementation, there are also some advantages. A thread local random is used to decide
         * if something should be recorded. This means that if there is a deterministic access pattern, it is now
         * possible to see what other accesses occur, rather than always dropping them. Second, after
         * {@link #TARGET_RECORDS} accesses, backoff occurs. This matches typical access patterns,
         * where there are either a high number of accesses (i.e. a cached buffer), or low (an ephemeral buffer), but
         * not many in between.
         * <p>
         * The use of atomics avoids serializing a high number of accesses, when most of the records will be thrown
         * away. High contention only happens when there are very few existing records, which is only likely when the
         * object isn't shared! If this is a problem, the loop can be aborted and the record dropped, because another
         * thread won the race.
         */
        private void record0(Object hint) {
            // Check TARGET_RECORDS > 0 here to avoid similar check before remove from and add to lastRecords

Frequently Asked Questions

What is the DefaultResourceLeak class?
DefaultResourceLeak is a class in the netty codebase, defined in common/src/main/java/io/netty/util/ResourceLeakDetector.java.
Where is DefaultResourceLeak defined?
DefaultResourceLeak is defined in common/src/main/java/io/netty/util/ResourceLeakDetector.java at line 399.

Analyze Your Own Codebase

Get architecture documentation, dependency graphs, and domain analysis for your codebase in minutes.

Try Supermodel Free