成人免费xxxxx在线视频软件_久久精品久久久_亚洲国产精品久久久_天天色天天色_亚洲人成一区_欧美一级欧美三级在线观看

面試官:說說Netty對象池的實(shí)現(xiàn)原理?

開發(fā) 架構(gòu)
對象池技術(shù)是一種重用對象以減少對象創(chuàng)建和銷毀帶來的開銷的方法。在對象池中,只有第一次訪問時(shí)會創(chuàng)建對象,并將其維護(hù)在內(nèi)存中,當(dāng)再次需要使用對象時(shí),會直接從對象池中獲取對象,并在使用完畢后歸還給對象池,而不是頻繁地創(chuàng)建和銷毀對象。

Netty 作為一個(gè)高性能的網(wǎng)絡(luò)通訊框架,它內(nèi)置了很多恰奪天工的設(shè)計(jì),目的都是為了將網(wǎng)絡(luò)通訊的性能做到極致,其中「對象池技術(shù)」也是實(shí)現(xiàn)這一目標(biāo)的重要技術(shù)。

1.什么是對象池技術(shù)?

對象池技術(shù)是一種重用對象以減少對象創(chuàng)建和銷毀帶來的開銷的方法。在對象池中,只有第一次訪問時(shí)會創(chuàng)建對象,并將其維護(hù)在內(nèi)存中,當(dāng)再次需要使用對象時(shí),會直接從對象池中獲取對象,并在使用完畢后歸還給對象池,而不是頻繁地創(chuàng)建和銷毀對象。

使用對象池技術(shù)的優(yōu)點(diǎn)有以下幾個(gè):

  • 提高性能:復(fù)用對象可以減少對象的創(chuàng)建和銷毀次數(shù),降低系統(tǒng)開銷,提高系統(tǒng)性能和吞吐量。
  • 減少內(nèi)存碎片:對象池可以避免頻繁地創(chuàng)建和銷毀對象,減少內(nèi)存碎片的產(chǎn)生,提高內(nèi)存利用率。
  • 避免頻繁GC:減少了對象的創(chuàng)建和銷毀,可以減少垃圾回收(GC)的頻率,降低系統(tǒng)的負(fù)擔(dān),提高系統(tǒng)的穩(wěn)定性。

2.對象池基本使用

Netty 對象池技術(shù)的核心實(shí)現(xiàn)類為 Recycler,Recycler 主要提供了以下 3 個(gè)方法:

  • get():獲取一個(gè)可重復(fù)使用的對象,如果對象池中有空閑對象,則返回其中一個(gè);否則會創(chuàng)建一個(gè)新對象。
  • recycle(T, Handle):回收一個(gè)對象,將對象放回對象池中以便下次復(fù)用。
  • newObject(Handle):當(dāng)對象池中沒有可用對象時(shí),此方法會被調(diào)用以創(chuàng)建新的對象實(shí)例。

接下來我們寫一個(gè) Recycler 對象池的使用 Demo,假設(shè)我們有一個(gè) User 類,需要實(shí)現(xiàn) User 對象的復(fù)用,具體實(shí)現(xiàn)代碼如下:

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

    static final class User {
        private String name;
        private Recycler.Handle<User> handle;
        public void setName(String name) {
            this.name = name;
        }
        public String getName() {
            return name;
        }
        public User(Recycler.Handle<User> handle) {
            this.handle = handle;
        }
        public void recycle() {
            handle.recycle(this);
        }
    }

    public static void main(String[] args) {
        User user1 = userRecycler.get();  // 1.從對象池獲取 User 對象
        user1.setName("zhangsan");    // 2.設(shè)置 User 對象的屬性
        user1.recycle();      // 3.回收對象到對象池
        User user2 = userRecycler.get();  // 4.從對象池獲取對象
        System.out.println(user1 == user2);
        System.out.println(user2.getName());
    }
}

以上程序的執(zhí)行結(jié)果如下:

true

zhangsan

從上述結(jié)果可以看出,當(dāng)?shù)谝淮握{(diào)用 userRecycler.get() 時(shí),因?yàn)閷ο蟪刂猩形创嬖?user 對象,所以創(chuàng)建了 name 為“zhangsan”的對象。但第二次再調(diào)用 userRecycler.get() 時(shí),因?yàn)閷ο蟪刂幸呀?jīng)存在了 user 對象,所以直接從對象池中取出了 user 對象,所以 user1==user2 時(shí),得到的結(jié)果是 true。

3.對象池技術(shù)應(yīng)用

在 Netty 中,使用 Recycler 對象池管理對象的常見類有以下幾個(gè):

  • PooledHeapByteBuf:管理堆內(nèi)存中的 ByteBuf 對象。
  • PooledDirectByteBuf:管理堆外內(nèi)存中的 ByteBuf 對象。
  • ChannelOutboundBuffer.Entry:Netty 出站緩沖區(qū)(ChannelOutboundBuffer)中,每一個(gè)待發(fā)送的消息都包裝在一個(gè) Entry 對象中。

4.實(shí)現(xiàn)原理

要搞清楚 Netty 對象池技術(shù)的實(shí)現(xiàn)原理,就要搞清楚 Netty 對象池的核心組件,以及組件之間的關(guān)系。

Netty 對象池技術(shù)的實(shí)現(xiàn)依靠以下 4 大組件:

  • Stack(棧):每個(gè)線程都關(guān)聯(lián)一個(gè) Stack(使用 FastThreadLocal 進(jìn)行存儲),用于存儲和管理該線程回收的對象。Stack 中存儲的是 DefaultHandle 對象,這些 DefaultHandle 對象包裝了實(shí)際要重用的對象。Stack 是與線程綁定的,每個(gè)線程從自己的 Stack 中獲取對象。
  • WeakOrderQueue(弱序隊(duì)列):當(dāng)某個(gè)線程(非主線程)回收對象時(shí),這些對象不會直接放入主線程的 Stack 中,而是放入 WeakOrderQueue 中。WeakOrderQueue 存儲的是從其他線程回收的對象,這些對象被包裝在 DefaultHandle 中。WeakOrderQueue 與 Stack 關(guān)聯(lián),但屬于非主線程。當(dāng)主線程的 Stack 為空時(shí),會嘗試從 WeakOrderQueue 中獲取對象。
  • Link(鏈表):WeakOrderQueue 中的存儲單元,用于存儲回收的對象。Link 中存儲的是 DefaultHandle 對象數(shù)組,這些數(shù)組包含從其他線程回收的對象。
  • DefaultHandle:對象的包裝類,在 Recycler 中緩存的對象都會包裝成 DefaultHandle 類。DefaultHandle 中存儲了實(shí)際要重用的對象,以及與之相關(guān)的元數(shù)據(jù)。

簡單來說,這 4 個(gè)組件的關(guān)系是,(每個(gè))線程為了保證線程安全和高效性操作,所以會把使用的對象放到 Stack 棧中,且每個(gè)線程都有自己的 Stack 棧。當(dāng)線程中的對象不再被使用時(shí)(也就是被回收時(shí)),并不會將回收對象直接放到 Stack 中(因?yàn)楫?dāng)前線程已經(jīng)不再使用了),此時(shí)會將對象存放到 WeakOrderQueue 隊(duì)列中,因?yàn)?WeakOrderQueue 隊(duì)列相當(dāng)于“線程共享的區(qū)域”,這樣其他線程就可以方便的從 WeakOrderQueue 中獲取對象進(jìn)行重用了。而 WeakOrderQueue 中的存儲單元是 Link 鏈表,它存儲的是對象池中的包裝對象 DefaultHandle,這就是這四大核心組件之間的關(guān)系。

5.線程如何獲取對象?

在 Netty 中,獲取對象池中對象的流程如下:

  • 判斷 Stack:線程首先會嘗試從自己的 Stack 中獲取對象。如果 Stack 中有對象,則直接彈出(pop)并返回。
  • Stack 為空:如果 Stack 為空,線程會檢查 WeakOrderQueue。如果 WeakOrderQueue 中有對象,則按照一定的規(guī)則(如“1/7規(guī)則”,每 7 個(gè)移動(dòng) 1 個(gè))將部分對象轉(zhuǎn)移到 Stack 中,然后從 Stack 中彈出并返回。
  • 創(chuàng)建新對象:如果 Stack 和 WeakOrderQueue 都為空,線程會調(diào)用 newObject() 方法創(chuàng)建一個(gè)新的對象,并包裝成 DefaultHandle 后放入 Stack 中,然后返回該對象。

通過這樣的設(shè)計(jì),Netty 的 Recycler 對象池技術(shù)能夠高效地重用對象,減少內(nèi)存分配和垃圾收集的開銷,提升性能。

責(zé)任編輯:姜華 來源: Java中文社群
相關(guān)推薦

2024-03-11 18:18:58

項(xiàng)目Spring線程池

2024-08-22 10:39:50

@Async注解代理

2024-03-05 10:33:39

AOPSpring編程

2024-05-30 08:04:20

Netty核心組件架構(gòu)

2024-02-29 16:49:20

volatileJava并發(fā)編程

2024-08-29 16:30:27

2024-08-12 17:36:54

2024-03-14 14:56:22

反射Java數(shù)據(jù)庫連接

2024-07-31 08:28:37

DMAIOMMap

2024-12-06 07:00:00

2024-03-22 06:56:24

零拷貝技術(shù)數(shù)據(jù)傳輸數(shù)據(jù)拷貝

2024-09-20 08:36:43

零拷貝數(shù)據(jù)傳輸DMA

2024-03-28 10:37:44

IoC依賴注入依賴查找

2025-02-28 00:00:00

2021-06-07 17:12:22

線程安全Atomic

2021-05-20 08:34:03

CDN原理網(wǎng)絡(luò)

2024-03-01 11:33:31

2024-12-04 14:45:14

零拷貝技術(shù)CPU 拷貝Zero-copy

2024-11-19 15:13:02

2023-12-27 18:16:39

MVCC隔離級別幻讀
點(diǎn)贊
收藏

51CTO技術(shù)棧公眾號

主站蜘蛛池模板: 超碰伊人 | 中文字幕在线第二页 | 999精品视频 | 天天干.com | 国产不卡在线 | 欧美二级| 狠狠躁18三区二区一区 | 91精品久久久久久久久久入口 | 91精品国产综合久久婷婷香蕉 | 久久无毛 | 久久99国产精品 | 久久九九99| 成人欧美一区二区三区黑人孕妇 | 国产精品久久久久久久久久久久 | 特黄色一级毛片 | 国产一区二区三区视频免费观看 | 久久新| 台湾a级理论片在线观看 | 黑人精品欧美一区二区蜜桃 | 成人欧美一区二区三区视频xxx | 久久成人午夜 | 日日操夜夜摸 | 国产精品久久久久久久免费观看 | 日韩成人一区 | 91久久久久久| 天天操操| 毛片久久久| www.久草 | 男女网站免费 | 日韩在线视频免费观看 | 精品av| 激情影院久久 | 成人免费观看男女羞羞视频 | 天天干亚洲 | 蜜桃av鲁一鲁一鲁一鲁 | 中文字幕亚洲在线 | av在线亚洲天堂 | 日韩一级 | 国产精品成人一区二区三区夜夜夜 | 91久久精品国产 | 精产国产伦理一二三区 |