JVM調(diào)優(yōu)

64位JDK應(yīng)用內(nèi)存問題

  1. 內(nèi)存回收導(dǎo)致的長時(shí)間停頓
  2. 現(xiàn)階段,64位JDK的性能測試結(jié)果普遍低于32位JDK
  3. 需要保證程序足夠穩(wěn)定,因?yàn)檫@種應(yīng)用要是產(chǎn)生堆溢出幾乎就無法產(chǎn)生堆轉(zhuǎn)儲(chǔ)快照(因?yàn)橐a(chǎn)生幾十GB乃至更大的Dump文件),哪怕產(chǎn)生了快照也幾乎無法進(jìn)行分析
  4. 相同程序在64位JDK消耗的內(nèi)存一般比32位JDK大,這是由于指針膨脹,以及數(shù)據(jù)類型對(duì)齊補(bǔ)白等因素導(dǎo)致的

集群優(yōu)化

  1. 盡量避免節(jié)點(diǎn)競爭全局的資源,最典型的就是磁盤競爭,各個(gè)節(jié)點(diǎn)如果同時(shí)訪問某個(gè)磁盤文件的話(尤其是并發(fā)寫操作容易出現(xiàn)問題),很容易導(dǎo)致IO異常
  2. 很難最高效率地利用某些資源池,譬如連接池,一般都是在各個(gè)節(jié)點(diǎn)建立自己獨(dú)立的連接池,這樣有可能導(dǎo)致一些節(jié)電池滿了而另外一些節(jié)點(diǎn)仍有較多空余。盡管可以使用集中式的JNDI,d但這個(gè)有一定復(fù)雜性并且有可能帶來額外的性能開銷
  3. 各個(gè)節(jié)點(diǎn)仍然不可避免地受到32位的內(nèi)存限制,在32位Windows平臺(tái)中每個(gè)進(jìn)程只能使用2GB的內(nèi)存,考慮到堆以外的內(nèi)存開銷,堆一般最多只能開到1.5GB。
  4. 大量使用本地緩存(如大量使用HashMap作為K/V緩存)的應(yīng)用,在邏輯集群中會(huì)造成較大的內(nèi)存浪費(fèi),因?yàn)槊總€(gè)邏輯節(jié)點(diǎn)上都有一份緩存,這時(shí)候可以考慮把本地緩存改為集中式緩存。

堆外內(nèi)存導(dǎo)致的溢出錯(cuò)誤

  1. Direct Memory:可通過-XX:MaxDirectMemorySize調(diào)整大小,內(nèi)存不足時(shí)拋出OutOfMemoryError或者OutOfMemoryError:Direct buffer memory
  2. 線程堆棧:可通過-Xss調(diào)整大小,內(nèi)存不足時(shí)拋出StackOverflowError(縱向無法分配,即無法分配新的棧幀)或者OutOfMemory:unable to create new native thread(橫向無法分配,即無法建立新的線程)
  3. Socket緩存區(qū):每個(gè)Socket連接都Receive和Send兩個(gè)緩存區(qū),分別占大約37KB和25KB內(nèi)存,連接多的話這塊內(nèi)存占用也比較可觀。如果無法分配,則可能會(huì)拋出IOException: too many open files異常
  4. JNI代碼:如果代碼中使用JNI調(diào)用本地庫,那本地庫使用的內(nèi)存也不在堆中
  5. 虛擬機(jī)和GC:虛擬機(jī)、GC的代碼執(zhí)行也要消耗一定的內(nèi)存

外部命令導(dǎo)致系統(tǒng)緩慢

如頻繁調(diào)用Java的Runtime.getRuntime().exec()方法

不恰當(dāng)數(shù)據(jù)結(jié)構(gòu)導(dǎo)致內(nèi)存占用過大

如HashMap<Long,Long>結(jié)構(gòu)來存儲(chǔ)數(shù)據(jù)文件空間效率太低。
在HashMap<Long,Long>結(jié)構(gòu)中,只有key和value所存放的兩個(gè)長整型數(shù)據(jù)是有效數(shù)據(jù),共16B。這兩個(gè)長整型數(shù)據(jù)包裝成java.lang.Long對(duì)象之后,就分別具有8B的MarkWord、8B的Klass指針,在加8B存儲(chǔ)數(shù)據(jù)的long值。在這兩個(gè)Long對(duì)象組成Map.entry之后,又多了16B的對(duì)象頭。然后一個(gè)8B的next字段和4B的int型的hash字段,為了對(duì)齊,還必須添加4B的空白填充,最后還有HashMap中對(duì)這個(gè)Entry的8B引用,這樣增加兩個(gè)長整型數(shù)字,實(shí)際消耗的內(nèi)存為(Long(24B)*2)+Entry(32B)+Hash Ref(8B)=88B,空間效率為16B/88B=18%

調(diào)整內(nèi)存設(shè)置控制垃圾收集頻率

如eclipse啟動(dòng)時(shí),F(xiàn)ull GC大多數(shù)是由于老年代容量擴(kuò)展而導(dǎo)致的,由永久代空間擴(kuò)展導(dǎo)致的也有一部分。為了避免這些擴(kuò)展導(dǎo)致的性能浪費(fèi),我們可以把-Xms和-XX:PermSize參數(shù)值設(shè)置為-Xmx和-XX:MaxPermSize參數(shù)值一樣,這樣就強(qiáng)制虛擬機(jī)在啟動(dòng)時(shí)就把老年代和永久代的容量固定下來,避免運(yùn)行時(shí)自動(dòng)擴(kuò)展。

?著作權(quán)歸作者所有,轉(zhuǎn)載或內(nèi)容合作請(qǐng)聯(lián)系作者
【社區(qū)內(nèi)容提示】社區(qū)部分內(nèi)容疑似由AI輔助生成,瀏覽時(shí)請(qǐng)結(jié)合常識(shí)與多方信息審慎甄別。
平臺(tái)聲明:文章內(nèi)容(如有圖片或視頻亦包括在內(nèi))由作者上傳并發(fā)布,文章內(nèi)容僅代表作者本人觀點(diǎn),簡書系信息發(fā)布平臺(tái),僅提供信息存儲(chǔ)服務(wù)。

相關(guān)閱讀更多精彩內(nèi)容

  • 1.一些概念 1.1.數(shù)據(jù)類型 Java虛擬機(jī)中,數(shù)據(jù)類型可以分為兩類:基本類型和引用類型?;绢愋偷淖兞勘4嬖?..
    落落落落大大方方閱讀 4,816評(píng)論 4 86
  • JVM參數(shù)的含義 并行收集器相關(guān)參數(shù) CMS相關(guān)參數(shù) 輔助信息 GC性能方面的考慮對(duì)于GC的性能主要有2個(gè)方面的指...
    jimjayce閱讀 1,198評(píng)論 1 1
  • 7.調(diào)優(yōu)方法 7.1.JVM調(diào)優(yōu)工具 Jconsole,jProfile,VisualVM Jconsole :j...
    天地征途_覺醒閱讀 843評(píng)論 0 0
  • 1.數(shù)據(jù)類型 堆(heap)與棧(stack)堆和棧是程序運(yùn)行的關(guān)鍵,很有必要它他們的關(guān)系說清楚。在java中,M...
    邵云濤閱讀 1,152評(píng)論 0 21
  • 今天周曰,忙碌了一周的生活終于可以停下來小憩一下。園里的小花小草們一定等我等急了,應(yīng)該迫不及待的翹首期盼著我吧。 ...
    斜陽斜閱讀 1,267評(píng)論 8 8

友情鏈接更多精彩內(nèi)容