国产 无码 综合区,色欲AV无码国产永久播放,无码天堂亚洲国产AV,国产日韩欧美女同一区二区

[Netty源碼] Netty輕量級對象池實現(xiàn)分析 (十三)

這篇具有很好參考價值的文章主要介紹了[Netty源碼] Netty輕量級對象池實現(xiàn)分析 (十三)。希望對大家有所幫助。如果存在錯誤或未考慮完全的地方,請大家不吝賜教,您也可以點擊"舉報違法"按鈕提交疑問。

1.對象池技術介紹

對象池其實就是緩存一些對象從而避免大量創(chuàng)建同一個類型的對象, 類似線程池。對象池緩存了一些已經(jīng)創(chuàng)建好的對象, 避免需要的時候創(chuàng)建。同時限制了實例的個數(shù)。

池化技術最終要的就是重復的使用池內(nèi)已經(jīng)創(chuàng)建的對象。

  • 創(chuàng)建對象的開銷大
  • 會創(chuàng)建大量的實例
  • 限制一些資源的使用

如果創(chuàng)建一個對象的開銷特別大, 那么需要提前創(chuàng)建一些可以使用的并緩存起來, 池化技術就是重復使用對象, 提前創(chuàng)建并緩存起來重復使用就是池化, 可以降低創(chuàng)建對象的開銷。

會大量創(chuàng)建實例的場景, 重復的使用對象可以減少創(chuàng)建的對象數(shù)量, 降低GC的壓力。

對于限制資源的使用更多的是一種保護機制, 比如數(shù)據(jù)庫連接池, 除去創(chuàng)建對象本身的開銷, 們對外部系統(tǒng)也會造成壓力, 比如大量創(chuàng)建鏈接對DB也是有壓力的。那么池化除了可以優(yōu)化資源外, 本身限制了資源數(shù), 對外部系統(tǒng)也起到了一層保護作用。

2.如何實現(xiàn)對象池

Apache Commons Pool, Netty輕量級對象池的實現(xiàn)。

Apache Commons Pool開源軟件庫提供了一個對象池API和一系列對象池的實現(xiàn), 支持各種配置, 比如活躍對象數(shù)或者閑置對象個數(shù)等。DBCP數(shù)據(jù)庫連接池基于Apache Commons Pool實現(xiàn)。

Netty自己實現(xiàn)了一套輕量級的對象池, 在多個IO線程獨立工作時候, 基于NioEventLoop的實現(xiàn), 每個IO線程輪詢單獨的Selector實例來檢索IO事件, 在IO來臨時候開始處理。最常見的IO操作就是讀寫, 具體到NIO就是從內(nèi)核緩沖區(qū)拷貝數(shù)據(jù)到用戶緩沖區(qū)或者從用戶緩沖區(qū)拷貝數(shù)據(jù)到內(nèi)核緩沖區(qū)。

3.Netty對象池實現(xiàn)分析

NIO提供了兩種Buffer最為緩沖區(qū): DirectByteBuffer和HeapByteBuffer, Netty進行了池化提供性能。

Netty的池化分別為PooledDirectByteBuf 和PolledHeapByteBuf。

static PooledDirectByteBuf newInstance(int maxCapacity) {
        PooledDirectByteBuf buf = RECYCLER.get();
        buf.reuse(maxCapacity);
        return buf;
    }

可見RECYCLER是池化的核心, 通過RECYCLER.get獲取一個實例。

Recycler就是Netty實輕量級池化技術的核心。

public class RecycleTest {
    private static final Recycler<User> RECYCLER = new Recycler<User>(){
        @Override
        protected User newObject(Handle<User> handle) {
            return new User(handle);
        }
    };

    public static class User{
        private final Recycler.Handle<User> handle;

        public User(Recycler.Handle<User> handle){
            this.handle = handle;
        }

        public void recycle(){
            handle.recycle(this);
        }
    }

    public static void main(String[] args) {
        // 1.獲取當前線程的stack
        // 2.從stack中彈出對象
        // 3.創(chuàng)建對象并綁定到stack
        User user = RECYCLER.get();
        user.recycle();
        User user1 = RECYCLER.get();
        System.out.println(user == user1);
    }
}
true
3.1 Recycler

整個對象池的核心實現(xiàn)由ThreadLocal, Handler和Stack及WrakOrderQueue構成。

[Netty源碼] Netty輕量級對象池實現(xiàn)分析 (十三)

[Netty源碼] Netty輕量級對象池實現(xiàn)分析 (十三)

  1. Stack相當于是一級緩存,同一個線程內(nèi)的使用和回收都將使用一個Stack
  2. 每個線程都會有一個自己對應的Stack,如果回收的線程不是Stack的線程,將元素放入到Queue中
  3. 所有的Queue組合成一個鏈表,Stack可以從這些鏈表中回收元素(實現(xiàn)了多線程之間共享回收的實例)

[Netty源碼] Netty輕量級對象池實現(xiàn)分析 (十三)

  • get(): 獲取對象
    public final T get() {
        if (maxCapacityPerThread == 0) {
            return newObject((Handle<T>) NOOP_HANDLE);
        }
        Stack<T> stack = threadLocal.get();
        DefaultHandle<T> handle = stack.pop();
        if (handle == null) {
            handle = stack.newHandle();
            handle.value = newObject(handle);
        }
        return (T) handle.value;
    }
  • 拿到當前線程對應的stack
  • 從stack中pop出一個元素
  • 如果不為空則返回,否則創(chuàng)建一個新的實例
    public final boolean recycle(T o, Handle<T> handle) {
        if (handle == NOOP_HANDLE) {
            return false;
        }

        DefaultHandle<T> h = (DefaultHandle<T>) handle;
        if (h.stack.parent != this) {
            return false;
        }

        h.recycle(o);
        return true;
    }
  • Recycler的recycle方法主要做了一些參數(shù)驗證。
3.2 Handler

recycle(): 放回池子中的方法, Recycler的recycle方法和DefaultHandle的recycle方法。

        @Override
        public void recycle(Object object) {
            if (object != value) {
                throw new IllegalArgumentException("object does not belong to handle");
            }

            Stack<?> stack = this.stack;
            if (lastRecycledId != recycleId || stack == null) {
                throw new IllegalStateException("recycled already");
            }

            stack.push(this);
        }
  • Recycler的recycle方法主要做了一些參數(shù)驗證。
  • DefaultHandle的recycle方法:
    1. 如果當前線程是當前stack對象的線程, 放入stack。
    2. 獲取當前線程對應的Map<Stack, WeakOrderQueue>, 實例放入stack對應的queue中。
3.3 Stack

Stack是對象池化背后存儲實例的數(shù)據(jù)結構, 如果能從stack中拿到可用的實例就不再創(chuàng)建新的實例。

        final Recycler<T> parent;
        final WeakReference<Thread> threadRef;
        final AtomicInteger availableSharedCapacity;
        final int maxDelayedQueues;

        private final int maxCapacity;
        private final int ratioMask;
        private DefaultHandle<?>[] elements;
        private int size;
        private int handleRecycleCount = -1; // Start with -1 so the first one will be recycled.
        private WeakOrderQueue cursor, prev;
        private volatile WeakOrderQueue head;

[Netty源碼] Netty輕量級對象池實現(xiàn)分析 (十三)

pop()

        DefaultHandle<T> pop() {
            int size = this.size;
            // 如過size = 0, scavenge
            if (size == 0) {
                if (!scavenge()) {
                    return null;
                }
                size = this.size;
            }
            size --;
            DefaultHandle ret = elements[size];
            elements[size] = null;
            if (ret.lastRecycledId != ret.recycleId) {
                throw new IllegalStateException("recycled multiple times");
            }
            ret.recycleId = 0;
            ret.lastRecycledId = 0;
            this.size = size;
            // 返回elements最后一個元素
            return ret;
        }

push(): 同線程和異步線程回收對象

[Netty源碼] Netty輕量級對象池實現(xiàn)分析 (十三)

同步線程回收對象

        private void pushNow(DefaultHandle<?> item) {
            if ((item.recycleId | item.lastRecycledId) != 0) {
                throw new IllegalStateException("recycled already");
            }
            item.recycleId = item.lastRecycledId = OWN_THREAD_ID;

            int size = this.size;
            if (size >= maxCapacity || dropHandle(item)) {
                return;
            }
            if (size == elements.length) {
                elements = Arrays.copyOf(elements, min(size << 1, maxCapacity));
            }

            elements[size] = item;
            this.size = size + 1;
        }

異步線程回收對象

  1. 獲取WeakOrderQueue
  2. 創(chuàng)建WeakOrderQueue
  3. 將對象追加到WeakOrderQueue
        private void pushLater(DefaultHandle<?> item, Thread thread) {
			// 獲取WeakOrderQueue
            Map<Stack<?>, WeakOrderQueue> delayedRecycled = DELAYED_RECYCLED.get();
            WeakOrderQueue queue = delayedRecycled.get(this);
            if (queue == null) {
                if (delayedRecycled.size() >= maxDelayedQueues) {
                    delayedRecycled.put(this, WeakOrderQueue.DUMMY);
                    return;
                }
                // 創(chuàng)建WeakOrderQueue
                if ((queue = WeakOrderQueue.allocate(this, thread)) == null) {
                    // drop object
                    return;
                }
                delayedRecycled.put(this, queue);
            } else if (queue == WeakOrderQueue.DUMMY) {
                // drop object
                return;
            }
			// 將對象追加到WeakOrderQueue
            queue.add(item);
        }

[Netty源碼] Netty輕量級對象池實現(xiàn)分析 (十三)

queue是一個隊列形式, 節(jié)點為Link, Link中是Handler (處理邏輯)

3.4 WeakOrderQueue
  head,tail:Link                       // 內(nèi)部元素的指針(WeakOrderQueue內(nèi)部存儲的是一個Link的鏈表)
  next:WeakOrderQueue     // 指向下一個WeakOrderQueue的指針
  owner:Thread                      // 對應的線程

[Netty源碼] Netty輕量級對象池實現(xiàn)分析 (十三)

WeakOrderQueue的結構圖

[Netty源碼] Netty輕量級對象池實現(xiàn)分析 (十三)

WeakOrderQueue中是一個一個Link組成

[Netty源碼] Netty輕量級對象池實現(xiàn)分析 (十三)

add方法將元素添加到自身的“隊列”中, transfer方法將自己擁有的元素“傳輸”到Stack中。

        void add(DefaultHandle<?> handle) {
            handle.lastRecycledId = id;

            Link tail = this.tail;
            int writeIndex;
            if ((writeIndex = tail.get()) == LINK_CAPACITY) {
                if (!head.reserveSpace(LINK_CAPACITY)) {
                    // Drop it.
                    return;
                }
                // We allocate a Link so reserve the space
                this.tail = tail = tail.next = new Link();

                writeIndex = tail.get();
            }
            tail.elements[writeIndex] = handle;
            handle.stack = null;
            // we lazy set to ensure that setting stack to null appears before we unnull it in the owning thread;
            // this also means we guarantee visibility of an element in the queue if we see the index updated
            tail.lazySet(writeIndex + 1);
        }

add操作將元素添加到tail指向的Link對象中,如果Link已滿則創(chuàng)建一個新的Link實例。

3.5 Link
        static final class Link extends AtomicInteger {
        	// 處理邏輯Handler
            private final DefaultHandle<?>[] elements = new DefaultHandle[LINK_CAPACITY];
			// 讀的指針
            private int readIndex;
            Link next;
        }

Link內(nèi)部包含了一個數(shù)組用于存放實例, 同時標記了讀取位置的索引和下一個Link元素的指針。

[Netty源碼] Netty輕量級對象池實現(xiàn)分析 (十三)

4.總結

Recyler -> Stack-> WeakOrderQueue -> Link -> Handler

[Netty源碼] Netty輕量級對象池實現(xiàn)分析 (十三)文章來源地址http://www.zghlxwxcb.cn/news/detail-417093.html

到了這里,關于[Netty源碼] Netty輕量級對象池實現(xiàn)分析 (十三)的文章就介紹完了。如果您還想了解更多內(nèi)容,請在右上角搜索TOY模板網(wǎng)以前的文章或繼續(xù)瀏覽下面的相關文章,希望大家以后多多支持TOY模板網(wǎng)!

本文來自互聯(lián)網(wǎng)用戶投稿,該文觀點僅代表作者本人,不代表本站立場。本站僅提供信息存儲空間服務,不擁有所有權,不承擔相關法律責任。如若轉載,請注明出處: 如若內(nèi)容造成侵權/違法違規(guī)/事實不符,請點擊違法舉報進行投訴反饋,一經(jīng)查實,立即刪除!

領支付寶紅包贊助服務器費用

相關文章

  • 基于yolov5輕量級的學生上課姿勢檢測識別分析系統(tǒng)

    基于yolov5輕量級的學生上課姿勢檢測識別分析系統(tǒng)

    在我之前的博文中已經(jīng)做過關于人體姿勢識別人體姿態(tài)檢測的博文,都是比較早期的技術模型了,隨機技術的迭代更新,很多更加出色的模型陸續(xù)出現(xiàn),這里基于一些比較好用的輕量級模型開發(fā)的姿態(tài)檢測模型。 原始博文如下: 《人體行為姿勢識別數(shù)據(jù)集WISDM實踐》 ? 《y

    2024年01月17日
    瀏覽(30)
  • 一種輕量級定時任務實現(xiàn)

    現(xiàn)在市面上有各式各樣的分布式定時任務,每個都有其獨特的特點,我們這邊的項目因為一開始使用的是分布式開源調度框架TBSchedule,但是這個框架依賴ZK, 由于ZK的不穩(wěn)定性和項目老舊無人維護 ,導致我們的定時任務會偶發(fā)出現(xiàn)異常,比如:任務停止、任務項丟失、任務不

    2024年02月14日
    瀏覽(96)
  • 一種輕量級websocket實現(xiàn)方案

    定義ws服務器工具類WsktUtil 開機啟動ws服務器 測試結果 自定義一個WebSocketClient子類 測試連接ws服務器 測試效果

    2024年02月15日
    瀏覽(21)
  • 輕量級狂雨小說cms系統(tǒng)源碼 v1.5.2 基于ThinkPHP5.1+MySQL

    輕量級狂雨小說cms系統(tǒng)源碼 v1.5.2 基于ThinkPHP5.1+MySQL

    輕量級狂雨小說cms系統(tǒng)源碼 v1.5.2 基于ThinkPHP5.1+MySQL的技術開發(fā) 狂雨小說cms提供一個輕量級小說網(wǎng)站解決方案,基于ThinkPHP5.1+MySQL的技術開發(fā)。 KYXSCMS,靈活,方便,人性化設計簡單易用是最大的特色,是快速架設小說類網(wǎng)站首選,只需5分鐘即可建立一個海量小說的行業(yè)網(wǎng)站,

    2024年02月07日
    瀏覽(21)
  • 使用es實現(xiàn)輕量級分布式鎖

    一般來說,實現(xiàn)分布式鎖的方式有哪幾種? 一:Redisson實現(xiàn) 二:ZK實現(xiàn) ??這兩種實現(xiàn)網(wǎng)上的實現(xiàn)是千篇一律,在本文就不做過多的講解了 ??其它方式好像沒有了,真的是這樣么? ??答案是否定的,今天我就給大家分享一個新的思路,使用es實現(xiàn)一個分布式鎖,分布式

    2024年02月06日
    瀏覽(103)
  • 輕量級軟件FastGithub實現(xiàn)穩(wěn)定訪問github

    輕量級軟件FastGithub實現(xiàn)穩(wěn)定訪問github

    當我們想訪問全球最大的“同性交友網(wǎng)站”https://github.com/ 時,總會出現(xiàn)無法訪問的界面,令人非??鄲溃?幸運的是,有一種輕量級的軟件可以幫助我們穩(wěn)定地訪問GitHub,那就是FastGithub。 FastGithub是一個簡潔且專一的軟件,它可以幫助你穩(wěn)定地訪問GitHub。FastGithub通過修改本地

    2024年02月06日
    瀏覽(19)
  • Spring Boot整合Postgres實現(xiàn)輕量級全文搜索

    Spring Boot整合Postgres實現(xiàn)輕量級全文搜索

    有這樣一個帶有搜索功能的用戶界面需求: 搜索流程如下所示: 這個需求涉及兩個實體: “評分(Rating)、用戶名(Username)”數(shù)據(jù)與 User 實體相關 “創(chuàng)建日期(create date)、觀看次數(shù)(number of views)、標題(title)、正文(body)”與 Story 實體相關 需要支持的功能對 User

    2024年02月19日
    瀏覽(91)
  • 教你使用PHP實現(xiàn)一個輕量級HTML模板引擎

    教你使用PHP實現(xiàn)一個輕量級HTML模板引擎

    ??作者簡介,黑夜開發(fā)者,全棧領域新星創(chuàng)作者?,2023年6月csdn上海賽道top4。多年電商行業(yè)從業(yè)經(jīng)驗,對系統(tǒng)架構,數(shù)據(jù)分析處理等大規(guī)模應用場景有豐富經(jīng)驗。 ??本文已收錄于PHP專欄:PHP進階實戰(zhàn)教程。 ??另有專欄PHP入門基礎教程,希望各位大佬多多支持??。 在 W

    2024年02月15日
    瀏覽(101)
  • OpenHarmony實戰(zhàn)開發(fā)-如何實現(xiàn)一個輕量級輸入法應用。

    OpenHarmony實戰(zhàn)開發(fā)-如何實現(xiàn)一個輕量級輸入法應用。

    ? 本示例使用inputMethodEngine實現(xiàn)一個輕量級輸入法應用kikaInput,支持在運行OpenHarmony OS的智能終端上。 使用說明 1.使用hdc shell aa start ability -a InputMethod -b cn.openharmony.inputmethodchoosedialog命令拉起切換輸入法彈窗,點擊kikainput切換輸入法到當前應用。 2.點擊應用中的編輯框,拉起

    2024年04月24日
    瀏覽(89)
  • Android:Linux上編譯OpenCV的Android庫,從源碼編譯出一個輕量級的OpenCV安卓庫

    (原文在這里,我根據(jù)這篇文章終于也能編譯成功可以使用的OpenCV庫文件了: Linux上編譯OpenCV的Android庫 https://zhuanlan.zhihu.com/p/301203711 整個編譯過程只用下載Android NDK和OpenCV源碼。工具鏈android.toolchain.cmake,是NDK:android-ndk-r19c-linux-x86_64自帶的,不用自己編譯了。使用WSL Ubuntu記

    2024年02月05日
    瀏覽(94)

覺得文章有用就打賞一下文章作者

支付寶掃一掃打賞

博客贊助

微信掃一掃打賞

請作者喝杯咖啡吧~博客贊助

支付寶掃一掃領取紅包,優(yōu)惠每天領

二維碼1

領取紅包

二維碼2

領紅包