從內存泄露、內存溢出和堆外內存,JVM優化參數配置參數

內存泄漏

內存泄漏是指程序在申請內存後,無法釋放已申請的內存空間,無用對象(不再使用的對象)持續佔有內存或無用對象的內存得不到及時釋放,從而造成內存空間的浪費。內存泄漏最終會導致OOM。

造成內存泄漏典型場景:

1. 單例模式的不正確使用單例對象在初始化後將在JVM的整個生命周期中以靜態變量的方式存在。如果單例對象持有對外部對象的引用,那麼這個對象將不能被JVM正常回收

2. 數據庫、網絡、IO連接沒有被關閉釋放這類連接,一般會提供close方法進行顯式關閉。但如果沒有進行close,是不會自動被gc回收的。3.不合適的對象引用

比如,生命周期長的對象持有生命周期短的對象的引用就很容易造成內存泄漏,儘管生命周期短的對象已經不再需要,但是因為生命周期長的對象持有對它的引用而導致不能被回收。


內存溢出

內存溢出即out of memory簡稱OOM。當程序申請內存時,沒有足夠的內存空間供其使用,往往會出現OOM。比如申請了一個Integer,但給它存了Long類型才能存下的數,那就會導致內存溢出。


堆外內存

關於堆內內存以及相應的內存回收策略,在之前的文章《JVM內存管理和垃圾回收》《JVM垃圾回收器、內存分配與回收策略》中已有介紹。對於堆外內存是指分配的對象直接受操作系統管理的JVM內存堆以外的空間。同時因為這部分區域直接受操作系統的管理,別的進程可以直接通過操作系統對其進行訪問,減少了從JVM中複製數據的過程。

堆外內存適用生命周期較長的對象,具有以下特點:

  1. 可以很方便的自主開闢很大的內存空間,對於大內存有良好的伸縮性
  2. 減少垃圾回收帶來的系統停頓時間
  3. 在進程間可以共享對象,減少JVM間的複製過程
  4. 適合那些分配次數少,讀寫操作頻繁的場景

但也存在如下缺點:

  1. 容易出現內存泄漏,並且很難排查
  2. 堆外內存的數據結構不直觀,當存儲結構複雜的對象時,會浪費大量的時間對其進行串行化

常用JVM配置參數

-Xms:JVM初始最小堆內存

-Xmx:JVM允許最大堆內存

-XX:PermSize:JVM初始非堆內存

-XX:MaxPermSize:JVM允許最大的非堆內存

-XX:+UseConcMarkSweepGC:年老代激活CMS收集器,可以盡量減少fullGC

-XX:+UseParNewGC:設置年輕代為多線程並行收集

-XX:+UseCMSCompactAtFullCollection:在full gc時,對老年代的壓縮(CMS的時候,會導致內存碎片,使內存空間不連續,可能會影響性能,但是可以消除碎片)


-XX:CMSInitiatingOccupancyFraction:當老年代被佔用空間達到一定比例時觸發CMS垃圾收集

-Xverify:none:類加載的時候關閉位元組碼驗證

-XX:+DisableExplicitGC:告訴JVM關掉System.gc

-XX:+CMSParallelRemarkEnabled:再標記算法,降低標記停頓時間

-XX:+PrintHeapAtGC:打印GC前後的詳細堆棧信息,主要用於生產環境或者壓力測試時候看的信息

-XX:+PrintGCTimeStamps:輸出GC的時間戳

-XX:PretenureSizeThreshold:使大對象直接進入老年代

關聯文章:

JVM內存管理和垃圾回收

JVM垃圾回收器、內存分配與回收策略

 


 

關注微信公眾號:大數據學習與分享,獲取更對技術乾貨