JAVA SOCKET bytebuffer 堆外記憶體__JAVA

來源:互聯網
上載者:User


廣義的堆外記憶體
說到堆外記憶體,那大家肯定想到堆內記憶體,這也是我們大家接觸最多的,我們在jvm參數裡通常設定-Xmx來指定我們的堆的最大值,不過這還不是我們理解的Java堆,-Xmx的值是新生代和老生代的和的最大值,我們在jvm參數裡通常還會加一個參數-XX:MaxPermSize來指定持久代的最大值,那麼我們認識的Java堆的最大值其實是-Xmx和-XX:MaxPermSize的總和,在分代演算法下,新生代,老生代和持久代是連續的虛擬位址,因為它們是一起分配的,那麼剩下的都可以認為是堆外記憶體(廣義的)了,這些包括了jvm本身在運行過程中分配的記憶體,codecache,jni裡分配的記憶體,DirectByteBuffer分配的記憶體等等

狹義的堆外記憶體
而作為java開發人員,我們常說的堆外記憶體溢出了,其實是狹義的堆外記憶體,這個主要是指java.nio.DirectByteBuffer在建立的時候分配記憶體,我們這篇文章裡也主要是講狹義的堆外記憶體,因為它和我們平時碰到的問題比較密切
JDK/JVM裡DirectByteBuffer的實現
DirectByteBuffer通常用在通訊過程中做緩衝池,在mina,netty等nio架構中屢見不鮮
通過上面的代碼我們知道可以通過-XX:MaxDirectMemorySize來指定最大的堆外記憶體
DirectByteBuffer在建立的時候會通過Unsafe的native方法來直接使用malloc分配一塊記憶體,這塊記憶體是heap 之外的,那麼自然也不會對gc造成什麼影響(System.gc除外),因為gc耗時的操作主要是操作heap之內的對象,對這塊記憶體的操作也是直接通過 Unsafe的native方法來操作的,相當於DirectByteBuffer僅僅是一個殼,還有我們通訊過程中如果資料是在Heap裡的,最終也還是會copy一份到堆外,然後再進行發送,所以為什麼不直接使用堆外記憶體呢。對於需要頻繁操作的記憶體,並且僅僅是臨時存在一會的,都建議使用堆外記憶體,並且做成緩衝池,不斷迴圈利用這塊記憶體。
如果我們大面積使用堆外記憶體並且沒有限制,那遲早會導致記憶體溢出,畢竟程式是跑在一台資源受限的機器上,因為這塊記憶體的回收不是你直接能控制的

聯繫我們

該頁面正文內容均來源於網絡整理,並不代表阿里雲官方的觀點,該頁面所提到的產品和服務也與阿里云無關,如果該頁面內容對您造成了困擾,歡迎寫郵件給我們,收到郵件我們將在5個工作日內處理。

如果您發現本社區中有涉嫌抄襲的內容,歡迎發送郵件至: info-contact@alibabacloud.com 進行舉報並提供相關證據,工作人員會在 5 個工作天內聯絡您,一經查實,本站將立刻刪除涉嫌侵權內容。

A Free Trial That Lets You Build Big!

Start building with 50+ products and up to 12 months usage for Elastic Compute Service

  • Sales Support

    1 on 1 presale consultation

  • After-Sales Support

    24/7 Technical Support 6 Free Tickets per Quarter Faster Response

  • Alibaba Cloud offers highly flexible support services tailored to meet your exact needs.