<ruby id="bdb3f"></ruby>

    <p id="bdb3f"><cite id="bdb3f"></cite></p>

      <p id="bdb3f"><cite id="bdb3f"><th id="bdb3f"></th></cite></p><p id="bdb3f"></p>
        <p id="bdb3f"><cite id="bdb3f"></cite></p>

          <pre id="bdb3f"></pre>
          <pre id="bdb3f"><del id="bdb3f"><thead id="bdb3f"></thead></del></pre>

          <ruby id="bdb3f"><mark id="bdb3f"></mark></ruby><ruby id="bdb3f"></ruby>
          <pre id="bdb3f"><pre id="bdb3f"><mark id="bdb3f"></mark></pre></pre><output id="bdb3f"></output><p id="bdb3f"></p><p id="bdb3f"></p>

          <pre id="bdb3f"><del id="bdb3f"><progress id="bdb3f"></progress></del></pre>

                <ruby id="bdb3f"></ruby>

                合規國際互聯網加速 OSASE為企業客戶提供高速穩定SD-WAN國際加速解決方案。 廣告
                jemalloc的另一個重要的概念是本地緩沖Thread-Local Storage,將釋放后的內存使用信息保存在線程中以提高內存分配效率。 在Netty中,擔負TLS的類有: * PoolThreadLocalCache 類似ThreadLocal對象,內部保存線程本地緩存 * PoolThreadCache 緩沖池,每個線程一個實例,保存回收的內存信息 * MemoryRegionCache 內部有一個隊列,保存了內存釋放時的數據Chunk和Handle * Recycler 一個輕量級對象池, ## 8.2.1 PoolThreadLocalCache PoolThreadLocalCache繼承FastThreadLocal對象,FastThreadLocal是netty自己實現的一直ThreadLocal機制,詳細實現可以參見ThreadLocal一節。我們可以將其當做一個普通的FastThreadLocal理解,每個線程保存了PoolThreadCache對象,使用get時,如果ThreadLocal內部沒有則會調用initialValue()方法創建。PoolThreadCache創建過程中會選擇內存使用最少的Arena來創建PoolThreadCache。 ``` final class PoolThreadLocalCache extends FastThreadLocal<PoolThreadCache> { @Override protected synchronized PoolThreadCache initialValue() { final PoolArena<byte[]> heapArena = leastUsedArena(heapArenas); final PoolArena<ByteBuffer> directArena = leastUsedArena(directArenas); return new PoolThreadCache( heapArena, directArena, tinyCacheSize, smallCacheSize, normalCacheSize, DEFAULT_MAX_CACHED_BUFFER_CAPACITY, DEFAULT_CACHE_TRIM_INTERVAL); } @Override protected void onRemoval(PoolThreadCache threadCache) { threadCache.free(); } private <T> PoolArena<T> leastUsedArena(PoolArena<T>[] arenas) { if (arenas == null || arenas.length == 0) { return null; } PoolArena<T> minArena = arenas[0]; for (int i = 1; i < arenas.length; i++) { PoolArena<T> arena = arenas[i]; if (arena.numThreadCaches.get() < minArena.numThreadCaches.get()) { minArena = arena; } } return minArena; } } ``` ## 8.2.2 PoolThreadCache PoolThreadCache記錄了線程本地保存的內存池,分配的ByteBuf釋放時會被保存到該對象的實例中。PoolThreadCache內部保存了tiny/small/normal的堆內存和直接內存的MemoryRegionCache數組 ``` final PoolArena<byte[]> heapArena; // 堆Arena final PoolArena<ByteBuffer> directArena; // 直接內存Arena private final MemoryRegionCache<byte[]>[] tinySubPageHeapCaches;// tiny-heap private final MemoryRegionCache<byte[]>[] smallSubPageHeapCaches;// small-heap private final MemoryRegionCache<byte[]>[] normalHeapCaches;// normal-heap private final MemoryRegionCache<ByteBuffer>[] tinySubPageDirectCaches;// tiny-direct private final MemoryRegionCache<ByteBuffer>[] smallSubPageDirectCaches;// small-direct private final MemoryRegionCache<ByteBuffer>[] normalDirectCaches;// normal-direct ``` 數組的大小與Arena中tinySubpagePools和smallSubpagePools的大小一樣,NormalMemoryRegionCache繼承了MemoryRegionCache對象,內部的queue保存了chunk和handle,根據這兩個可以定位到chunk中對應的范圍。 ## 8.2.3 Recycler Recycler是一個基于ThreadLocal棧的輕量級的對象池,在實現上,線程內部的threadLocal保存Stack對象,Stack內部保存了Handler, 內部有一個Handle接口,recycle方法用來回收對象 ``` public interface Handle<T> { void recycle(T object); } ``` 在使用時,需要重寫Recycler的newObject方法,該方法會在get時使用,如果本地線程池沒有可重復使用的對象則調用newObject返回一個新對象。 ``` // public static Recycler<MObject> RECYCLER = new Recycler<MObject>() { @Override protected MObject newObject(Handle<MObject> handle) { return new MObject(handle); } }; ``` 之后,我們就可以講對象的獲取交給RECYCLER處理 ``` public static void main(String[] args) { MObject obj1 = RECYCLER.get();// 獲取對象 System.out.println(obj1); // obj1 地址 1418370913 MObject obj2 = RECYCLER.get(); // 再次獲取 System.out.println(obj2); // obj2 地址 361993357 obj1.free(); obj2.free(); System.out.println(RECYCLER.get());// 地址1418370913,重用了obj1 System.out.println(RECYCLER.get());// 地址625576447 創建了新對象 } ``` Recycler的get方法,首先從本地獲取stack,如果為空會創建并保存到線程本地。之后從stack中獲取對象,如果存在則返回。注意stack中的對象是Handler對象,Handler的value才是newObject返回的對象。 ``` public final T get() { if (maxCapacityPerThread == 0) { return newObject((Handle<T>) NOOP_HANDLE); } Stack<T> stack = threadLocal.get(); // 從本地stack中獲取 沒有則創建 DefaultHandle<T> handle = stack.pop(); // 獲取stack里面的handler if (handle == null) { // 如果handler為空,則創建一個, handle = stack.newHandle(); handle.value = newObject(handle); // 創建對象 } return (T) handle.value; } ``` 釋放對象時,需要通過Handler的recycle方法完成, ``` public void recycle(Object object) { if (object != value) { throw new IllegalArgumentException("object does not belong to handle"); } stack.push(this); } ```
                  <ruby id="bdb3f"></ruby>

                  <p id="bdb3f"><cite id="bdb3f"></cite></p>

                    <p id="bdb3f"><cite id="bdb3f"><th id="bdb3f"></th></cite></p><p id="bdb3f"></p>
                      <p id="bdb3f"><cite id="bdb3f"></cite></p>

                        <pre id="bdb3f"></pre>
                        <pre id="bdb3f"><del id="bdb3f"><thead id="bdb3f"></thead></del></pre>

                        <ruby id="bdb3f"><mark id="bdb3f"></mark></ruby><ruby id="bdb3f"></ruby>
                        <pre id="bdb3f"><pre id="bdb3f"><mark id="bdb3f"></mark></pre></pre><output id="bdb3f"></output><p id="bdb3f"></p><p id="bdb3f"></p>

                        <pre id="bdb3f"><del id="bdb3f"><progress id="bdb3f"></progress></del></pre>

                              <ruby id="bdb3f"></ruby>

                              哎呀哎呀视频在线观看