JVM參數之MaxDirectMemorySize


1、Java_JVM參數-XX:MaxDirectMemorySize 與 兩種 ByteBuffer: heap,direct ByteBuffer(參考:https://www.cnblogs.com/laoqing/p/10380536.html)

     ByteBuffer有兩種:
     heap ByteBuffer -> -XX:Xmx
     1.1、一種是heap ByteBuffer,該類對象分配在JVM的堆內存里面,直接由Java虛擬機負責垃圾回收;

     direct ByteBuffer -> -XX:MaxDirectMemorySize
     1.2、一種是direct ByteBuffer是通過jni在虛擬機外內存中分配的。通過jmap無法查看該快內存的使用情況。只能通過top來看它的內存使用情況。
           1.2.1、JVM堆內存大小可以通過-Xmx來設置,同樣的direct ByteBuffer可以通過-XX:MaxDirectMemorySize來設置,此參數的含義是當Direct ByteBuffer分配的堆外內存到達指定大小后,即觸發Full GC。注意該值是有上限的,默認是64M,最大為sun.misc.VM.maxDirectMemory(),在程序中中可以獲得-XX:MaxDirectMemorySize的設置的值。
           1.2.2、沒有配置MaxDirectMemorySize的,因此MaxDirectMemorySize的大小即等於-Xmx
           1.2.3、Direct Memory的回收機制,Direct Memory是受GC控制的
           1.2.4、對於使用Direct Memory較多的場景,需要注意下MaxDirectMemorySize的設置,避免-Xmx + Direct Memory超出物理內存大小的現象

2、用JDK8的一定要配置:-Xms -Xmx -XX:MaxDirectMemorySize,【Xmx +(加) MaxDirectMemorySize】的值不能超過docker的最大內存,不然docker內存占滿了會被oomkill掉;

     沒配置參數導致的問題以及處理參考:http://hellojava.info/?tag=maxdirectmemorysize (物理內存耗盡、CMS GC碎片造成RT慢的兩個Case
    分析:https://my.oschina.net/go4it/blog/3029481

3、dmesg排查消失的進程:
      3.1、適用場景:

              如果發現自己的java進程悄無聲息的消失了,幾乎沒有留下任何線索,那么dmesg一發,很有可能有你想要的。

      3.2、具體操作
              sudo dmesg|grep -i kill | less 或者 dmesg | grep kill

      去找關鍵字oom_killer,找到的結果類似如下:
      [6710782.021013] java invoked oom-killer: gfp_mask=0xd0, order=0, oom_adj=0, oom_scoe_adj=0 
      [6710782.070639] [] ? oom_kill_process+0x68/0x140 
      [6710782.257588] Task in /LXC011175068174 killed as a result of limit of /LXC011175068174 
      [6710784.698347] Memory cgroup out of memory: Kill process 215701 (java) score 854 or sacrifice child 
      [6710784.707978] Killed process 215701, UID 679, (java) total-vm:11017300kB, anon-rss:7152432kB, file-rss:1232kB

       以上表明,對應的java進程被系統的OOM Killer給干掉了,得分為854. 
       解釋一下OOM killer(Out-Of-Memory killer),該機制會監控機器的內存資源消耗。當機器內存耗盡前,該機制會掃描所有的進程(按照一定規則計算,內存占用,時間等),挑選出得分最高的進程,然后殺死,從而保護機器。

 

       dmesg日志時間轉換公式: 
       log實際時間=格林威治1970-01-01+(當前時間秒數-系統啟動至今的秒數+dmesg打印的log時間)秒數:
       date -d “1970-01-01 UTC echo "$(date +%s)-$(cat /proc/uptime|cut -f 1 -d' ')+12288812.926194"|bc seconds”
       剩下的,就是看看為什么內存這么大,觸發了OOM-Killer了。

4、默認情況下,VM將用於直接字節緩沖區的堆內存量限制為最大堆大小的大約85%

 http://lovestblog.cn/blog/2015/05/12/direct-buffer/

 

附:幾種內存溢出處理辦法:cnblogs.com/leasonWang/p/11146030.html

 


免責聲明!

本站轉載的文章為個人學習借鑒使用,本站對版權不負任何法律責任。如果侵犯了您的隱私權益,請聯系本站郵箱yoyou2525@163.com刪除。



 
粵ICP備18138465號   © 2018-2025 CODEPRJ.COM