Netty 作為一個高性能的網絡通訊框架,它內置了很多恰奪天工的設計,目的都是為了將網絡通訊的性能做到極致,其中「對象池技術」也是實現這一目標的重要技術。
對象池技術是一種重用對象以減少對象創建和銷毀帶來的開銷的方法。在對象池中,只有第一次訪問時會創建對象,并將其維護在內存中,當再次需要使用對象時,會直接從對象池中獲取對象,并在使用完畢后歸還給對象池,而不是頻繁地創建和銷毀對象。
使用對象池技術的優點有以下幾個:
Netty 對象池技術的核心實現類為 Recycler,Recycler 主要提供了以下 3 個方法:
接下來我們寫一個 Recycler 對象池的使用 Demo,假設我們有一個 User 類,需要實現 User 對象的復用,具體實現代碼如下:
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.設置 User 對象的屬性 user1.recycle(); // 3.回收對象到對象池 User user2 = userRecycler.get(); // 4.從對象池獲取對象 System.out.println(user1 == user2); System.out.println(user2.getName()); }}
以上程序的執行結果如下:
true
zhangsan
從上述結果可以看出,當第一次調用 userRecycler.get() 時,因為對象池中尚未存在 user 對象,所以創建了 name 為“zhangsan”的對象。但第二次再調用 userRecycler.get() 時,因為對象池中已經存在了 user 對象,所以直接從對象池中取出了 user 對象,所以 user1==user2 時,得到的結果是 true。
在 Netty 中,使用 Recycler 對象池管理對象的常見類有以下幾個:
要搞清楚 Netty 對象池技術的實現原理,就要搞清楚 Netty 對象池的核心組件,以及組件之間的關系。
Netty 對象池技術的實現依靠以下 4 大組件:
簡單來說,這 4 個組件的關系是,(每個)線程為了保證線程安全和高效性操作,所以會把使用的對象放到 Stack 棧中,且每個線程都有自己的 Stack 棧。當線程中的對象不再被使用時(也就是被回收時),并不會將回收對象直接放到 Stack 中(因為當前線程已經不再使用了),此時會將對象存放到 WeakOrderQueue 隊列中,因為 WeakOrderQueue 隊列相當于“線程共享的區域”,這樣其他線程就可以方便的從 WeakOrderQueue 中獲取對象進行重用了。而 WeakOrderQueue 中的存儲單元是 Link 鏈表,它存儲的是對象池中的包裝對象 DefaultHandle,這就是這四大核心組件之間的關系。
在 Netty 中,獲取對象池中對象的流程如下:
通過這樣的設計,Netty 的 Recycler 對象池技術能夠高效地重用對象,減少內存分配和垃圾收集的開銷,提升性能。
本文鏈接:http://www.www897cc.com/showinfo-26-92142-0.html面試官:說說Netty對象池的實現原理?
聲明:本網頁內容旨在傳播知識,若有侵權等問題請及時與本網聯系,我們將在第一時間刪除處理。郵件:2376512515@qq.com