寫NIO程序時,常用ByteBuffer來讀取寫入數據,那使用ByteBuffer.allocate()仍是ByteBuffer.allocateDirect分配呢?java
咱們但願使用速度更快的方式,可是沒有GC管理會產生OOM的問題。react
好在OS內存在java中有個DirectByteBuffer與之對應,當GC發生時,這個類會被回收,對應的OS內存會被回收,這樣就知足了咱們的想法。 可是若是堆內一直夠用,不觸發GC,DirectByteBuffer不進行GC呢?對應的OS內存也不會回收。緩存
既然自動GC方式不靠譜,好在DirectByteBuffer裏面有個Cleaner對象,裏面有個clean()方法,經過這個方法咱們能夠經過手動方式釋放了。jvm
分配-Xmx=100m,沒有設置-XX:MaxDirectMemorySize,默認大小和-Xmx大小相同測試
//分配128MB直接內存 ByteBuffer bb = ByteBuffer.allocateDirect(10241024128);code
產生OOM;對象
一樣的代碼產生OOM;內存
public static void main(String[] args) throws InterruptedException{ //分配512MB直接緩存 ByteBuffer bb = ByteBuffer.allocateDirect(10241024512);it
TimeUnit.SECONDS.sleep(10); //清除直接緩存 ((DirectBuffer)bb).cleaner().clean(); TimeUnit.SECONDS.sleep(10); System.out.println("ok"); }
以後經過觀察內存使用變化,發現從以前一直升高,到調用clean()以後,內存降下來,說明clean()方法生效了。io