配置jvm堆最大内存eden区与s0或者s1区域比例
生活随笔
收集整理的這篇文章主要介紹了
配置jvm堆最大内存eden区与s0或者s1区域比例
小編覺得挺不錯的,現在分享給大家,幫大家做個參考.
配置堆內存大小,其實比較簡單,你們以后做JVM調優,主要是圍繞著哪個內存區域,都是圍繞著堆內存的,像棧每次用完之后都會自動釋放的,還有方法區,但是方法區你不用考慮,因為它如果滿的情況下,垃圾回收會自動去回收,但是主要還是圍繞堆內存的,我們怎么去配置堆內存大小,在這里給你們介紹幾個方法
package com.learn.test;/*** 我們怎么去配置堆內存大小* 打印一下堆內存的一些基本的大小* @author Leon.Sun**/
public class Test001 {public static void main(String[] args) {/*** 4 * 1024 * 1024這樣是4個兆的空間* 你們猜一下已使用內存是多少兆* 是不是至少在9M以上* 5家4嘛* 可不可能小于9兆* 肯定是大于9M以上* 你們想想是不是這樣的* 已經使用內存10M* 我們運行是不是這樣的* 10M* 為什么會多出1兆出來* 因為它底層也會做一些處理操作的* 可能有誤差* 但是誤差不大* 一般在幾兆左右* 肯定是會大于9M以上的* 這個是堆內存大小* 過來我會將內存泄露怎么解決* 這個配置JVM堆內存的大小應該不難吧* 我這里能不能配置25M*/// byte[] b = new byte[4 * 1024 * 1024];/*** 我能不能申請25M的空間* java.lang.OutOfMemoryError: Java heap space* 這個你們遇見過是不是* 我只是演示一個效果* 待會講怎么解決* 一開始的時候為什么不會溢出* -Xmx20m -Xms5m* 我把這個配置刪掉* 因為一開始默認是4個G的內存* 這綽綽有余* 肯定是沒有任何影響的* 你看這個就沒有溢出了* 堆內存配置的話比較容易* */byte[] b = new byte[25 * 1024 * 1024];System.out.println("分配了25M空間給數組");/*** 打印JVM一些基本的參數* 第一個參數表示堆的最大內存* 最大內存1803M* 你們知道他們是按照什么單位來換算的* 兆的下一個單位是字節* 他這個比較小* 你們最好是/1024/1024* 這樣就換算成兆了* 你們看到1803M* 1803M大概等于多少G呢* 差不多2個G* 可能有一些內存被占用掉了* 默認是4個G的* 可能你的電腦打印出來也不一樣* 因為每臺電腦都不一樣* 所以多多少少會有點誤差* 你們都按照四舍五入去算就行了* 默認都是4個G的內存* 我以前帶電腦是8個G的時候默認是8個G的* 這是默認的* -Xmx20m -Xms5m* 這個參數什么意思* 表示我當前最大可用堆內存是20M* 然后初始的是為5M* 你們找到Run as里面* 然后Run Configuration* 然后你把參數就放到Arguments的VM arguments* 表示我這個項目啟動起來之后,* 他最大的堆內存是20M* 他的初始值是5M* * 最大內存18M* 有的人說不對啊* 我明明設置的是20M* 怎么變成18M了* 我已經講過了* 這個多多少少會有點誤差* 但是大家不要去糾結這個誤差* */System.out.println("最大內存" + Runtime.getRuntime().maxMemory() / 1024 / 1024 + "M");/*** 第二個可用的內存* 可用內存96M* 默認可用的是96M* * 可用內存4M*/System.out.println("可用內存" + Runtime.getRuntime().freeMemory() / 1024 / 1024 + "M");/*** 已經使用的內存* 已經使用內存123M* * 已經使用內存5M* 這個時候可以看到已經使用的內存是5M* 這個已經使用的內存是什么意思嗎* 已使用的內存是根據你初始值申請來的* 你在這邊可以看一下* -Xmx20m -Xms5m* 在這邊我申請的初始值是5m*/System.out.println("已經使用內存" + Runtime.getRuntime().totalMemory() / 1024 / 1024 + "M");}}
首先這個是堆內存,堆內存新生代和老年代一般是1:2,左邊我們叫做新生代,右邊叫做老年代,新生代又有一個eden區,接著還有S0區和S1區,S0還有一個名字叫from區,默認的是8:1:1,這個看你們公司,每個公司的項目不一樣,eden區比S0區大了還是小了記住肯定是要大的,S0區和S1區的主要作用是干嘛,做復制功能,你沒必要把它搞的特別大,特別大的情況下會特別的占用內存的,所以默認情況是8:1:1,其實8:1:1也不是很好,如果我對象特別多的情況下,你如果還是做成8:1:1的情況下,你知道會產生什么情況嗎,s0區可能裝不滿的,所以也會導致頻繁的GC的回收,所以要看你在什么應用場景,我看過我們的項目是怎么配的呢,就是2:1:1,但是我們的項目比較大,絕大部分的對象還是會存放到老年代里去的,根據不同的公司,這個看你們公司的,我們配置新生代的比例,我們講一個參數,-XX:+PrintGCDetails這個參數,這個參數誰知道是干嘛用的,打印詳細的GC日志,GC日志到時給你演示一遍,當它發生GC回收的時候,都會打印一個GC日志
?
package com.learn.test;/*** 配置新生代比例大小* 什么是新生代* 我們剛出生的都是在eden區里面* 如果eden區滿的時候會GC的* @author Leon.Sun* -Xms20m -Xmx20m -Xmn1m -XX:SurvivorRatio=2 -XX:+PrintGCDetails -XX:+UseSerialGC* 首先堆內存是20M* 堆內存最大值是20M* 新生代-Xmn最大值是1M* eden區和s0/s1區的比例是2:1* -XX:SurvivorRatio這個參數干嘛用的* 它是配置eden區和from/to區的一個比列* 用來設置新生代eden空間和from/to空間的比例* from區和to區的比例都是相等的* 相當于eden區占兩份,* S0區占一份,S1區也占一份* 第一次你是看到配置的選項的,* 你要先運行這個JAVA代碼* 然后你就可以去Run as -> Run Configration看到記錄* 然后你就可以配置VM arguments* 這個說細點* 免得你們下次不知道怎么配了* -Xms20m -Xmx20m -Xmn2m -XX:SurvivorRatio=2 -XX:+PrintGCDetails -XX:+UseSerialGC* [GC (Allocation Failure) [DefNew: 1024K->512K(1536K), 0.0014710 secs]* 這個表示空間不夠了進行回收垃圾* 首先你們可以看到這幾個參數* eden space 1024K* 首先可以看到eden區* eden區是1024K* from space 512K* from區是512K* to space 512K* to區是512K* -XX:SurvivorRatio=2這個參數配置什么意思* SurvivorRatio=2 配置新生代中 eden from to 比例關系 2 1 1* 1024K除以2是不是512K了* -Xms20m -Xmx20m -Xmn2m -XX:SurvivorRatio=2 -XX:+PrintGCDetails -XX:+UseSerialGC* 我們把這個配置刪掉* 我們只留-XX:+PrintGCDetails -XX:+UseSerialGC這個信息* 只留GC的日志信息* -XX:+UseSerialGC這個是配置串行回收* 這個時候我們來運行一遍來看這個效果* 你們有沒有發現一個問題* 這一次運行沒有發生GC回收的* 你們有沒有仔細觀察* -Xms20m -Xmx20m -Xmn2m -XX:SurvivorRatio=2 -XX:+PrintGCDetails -XX:+UseSerialGC* 我這個時候把堆內存設置為20M* 堆內存最大內存為20M的情況下* 他就會發生一個GC日志[GC (Allocation Failure)* 那這個GC日志是什么GC* 你們說這個程序運行的時候需要幾兆* 運行的時候至少是需要10M以上* 因為我循環了10次* 但是你新生代只有2m* 你新生代是2兆* 這個時候你又要裝10兆* 你要往新生代放10次2M的話* 新生代空間根本就不夠* 因為新生代只有2M內存* 這樣我就不夠用* 為了防止內存溢出的情況下* 包括防止內存泄露的情況下* 我就不停的進行回收* 這樣我才有新的可以進來* 如果內存不足的情況下會發生不斷地去進行回收的* 如果內存非常足的情況下他去回收干嘛* 類似與我們生活中你那么有錢你還要去搶錢干嘛* 其實是一個道理* 你們可以算一下* 默認的我們可以算一下* 34944K除以4352K等于8* 你們覺得這個比例是多少* 8:1:1* eden:from:to* 你們如果仔細算有點誤差也是很正常的* 不要糾結少了幾十K* 這個很正常* */ public class Test002 {public static void main(String[] args) {byte[] b = null;for (int i = 0; i < 10; i++) {b = new byte[1 * 1024 * 1024];}} }?
總結
以上是生活随笔為你收集整理的配置jvm堆最大内存eden区与s0或者s1区域比例的全部內容,希望文章能夠幫你解決所遇到的問題。
- 上一篇: 常见jvm参数配置
- 下一篇: 设置新生代与老年代比例关系