Home / Class/ Magazine Class — netty Architecture

Magazine Class — netty Architecture

Architecture documentation for the Magazine class in AdaptivePoolingAllocator.java from the netty codebase.

Entity Profile

Dependency Diagram

graph TD
  03ccb368_d6fc_bee6_64d5_0e674ae8c01f["Magazine"]
  fee3fa6d_a7fb_30d6_ea34_49602c633a2c["AdaptivePoolingAllocator.java"]
  03ccb368_d6fc_bee6_64d5_0e674ae8c01f -->|defined in| fee3fa6d_a7fb_30d6_ea34_49602c633a2c
  41097f8a_1d62_d8d9_681a_240be71758b9["Magazine()"]
  03ccb368_d6fc_bee6_64d5_0e674ae8c01f -->|method| 41097f8a_1d62_d8d9_681a_240be71758b9
  4a58da3c_40d1_32f5_6976_57fdd64dc888["tryAllocate()"]
  03ccb368_d6fc_bee6_64d5_0e674ae8c01f -->|method| 4a58da3c_40d1_32f5_6976_57fdd64dc888
  2845f5ec_6a60_22de_f8d4_345bc5446f42["allocateWithoutLock()"]
  03ccb368_d6fc_bee6_64d5_0e674ae8c01f -->|method| 2845f5ec_6a60_22de_f8d4_345bc5446f42
  b550a3a7_b98a_e36b_d58d_413aa6587ed4["allocate()"]
  03ccb368_d6fc_bee6_64d5_0e674ae8c01f -->|method| b550a3a7_b98a_e36b_d58d_413aa6587ed4
  0a745cad_53b5_e976_8e80_cfe56a86673e["restoreMagazineFreed()"]
  03ccb368_d6fc_bee6_64d5_0e674ae8c01f -->|method| 0a745cad_53b5_e976_8e80_cfe56a86673e
  33bb02aa_95f4_9821_7021_dcda1b551bd1["transferToNextInLineOrRelease()"]
  03ccb368_d6fc_bee6_64d5_0e674ae8c01f -->|method| 33bb02aa_95f4_9821_7021_dcda1b551bd1
  700c009a_e442_12d4_0cb8_4fba0ab43bc1["free()"]
  03ccb368_d6fc_bee6_64d5_0e674ae8c01f -->|method| 700c009a_e442_12d4_0cb8_4fba0ab43bc1
  b3f079a5_0926_add8_c980_b8a5b35deac5["AdaptiveByteBuf()"]
  03ccb368_d6fc_bee6_64d5_0e674ae8c01f -->|method| b3f079a5_0926_add8_c980_b8a5b35deac5
  3e789ca7_f805_04a7_37bc_e818b4066279["offerToQueue()"]
  03ccb368_d6fc_bee6_64d5_0e674ae8c01f -->|method| 3e789ca7_f805_04a7_37bc_e818b4066279

Relationship Graph

Source Code

buffer/src/main/java/io/netty/buffer/AdaptivePoolingAllocator.java lines 787–1052

    private static final class Magazine {
        private static final AtomicReferenceFieldUpdater<Magazine, Chunk> NEXT_IN_LINE;
        static {
            NEXT_IN_LINE = AtomicReferenceFieldUpdater.newUpdater(Magazine.class, Chunk.class, "nextInLine");
        }
        private static final Chunk MAGAZINE_FREED = new Chunk();

        private static final class AdaptiveRecycler extends Recycler<AdaptiveByteBuf> {

            private AdaptiveRecycler(boolean unguarded) {
                // uses fast thread local
                super(unguarded);
            }

            private AdaptiveRecycler(int maxCapacity, boolean unguarded) {
                // doesn't use fast thread local, shared
                super(maxCapacity, unguarded);
            }

            @Override
            protected AdaptiveByteBuf newObject(final Handle<AdaptiveByteBuf> handle) {
                return new AdaptiveByteBuf((EnhancedHandle<AdaptiveByteBuf>) handle);
            }

            public static AdaptiveRecycler threadLocal() {
                return new AdaptiveRecycler(true);
            }

            public static AdaptiveRecycler sharedWith(int maxCapacity) {
                return new AdaptiveRecycler(maxCapacity, true);
            }
        }

        private static final AdaptiveRecycler EVENT_LOOP_LOCAL_BUFFER_POOL = AdaptiveRecycler.threadLocal();

        private Chunk current;
        @SuppressWarnings("unused") // updated via NEXT_IN_LINE
        private volatile Chunk nextInLine;
        private final MagazineGroup group;
        private final ChunkController chunkController;
        private final StampedLock allocationLock;
        private final AdaptiveRecycler recycler;

        Magazine(MagazineGroup group, boolean shareable, ChunkController chunkController) {
            this.group = group;
            this.chunkController = chunkController;

            if (shareable) {
                // We only need the StampedLock if this Magazine will be shared across threads.
                allocationLock = new StampedLock();
                recycler = AdaptiveRecycler.sharedWith(MAGAZINE_BUFFER_QUEUE_CAPACITY);
            } else {
                allocationLock = null;
                recycler = null;
            }
        }

        public boolean tryAllocate(int size, int maxCapacity, AdaptiveByteBuf buf, boolean reallocate) {
            if (allocationLock == null) {
                // This magazine is not shared across threads, just allocate directly.
                return allocate(size, maxCapacity, buf, reallocate);
            }

            // Try to retrieve the lock and if successful allocate.
            long writeLock = allocationLock.tryWriteLock();
            if (writeLock != 0) {
                try {
                    return allocate(size, maxCapacity, buf, reallocate);
                } finally {
                    allocationLock.unlockWrite(writeLock);
                }
            }
            return allocateWithoutLock(size, maxCapacity, buf);
        }

        private boolean allocateWithoutLock(int size, int maxCapacity, AdaptiveByteBuf buf) {
            Chunk curr = NEXT_IN_LINE.getAndSet(this, null);
            if (curr == MAGAZINE_FREED) {
                // Allocation raced with a stripe-resize that freed this magazine.
                restoreMagazineFreed();
                return false;

Frequently Asked Questions

What is the Magazine class?
Magazine is a class in the netty codebase, defined in buffer/src/main/java/io/netty/buffer/AdaptivePoolingAllocator.java.
Where is Magazine defined?
Magazine is defined in buffer/src/main/java/io/netty/buffer/AdaptivePoolingAllocator.java at line 787.

Analyze Your Own Codebase

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

Try Supermodel Free