jvm解决堆内存溢出问题
生活随笔
收集整理的這篇文章主要介紹了
jvm解决堆内存溢出问题
小編覺得挺不錯的,現(xiàn)在分享給大家,幫大家做個參考.
我們講一下堆溢出,棧溢出,還有方法區(qū)的溢出,這就講了一個概念,內(nèi)存溢出和內(nèi)存泄露的區(qū)別是什么,這個概念很混淆,內(nèi)存泄露怎么又包含內(nèi)存溢出,內(nèi)存溢出和內(nèi)存泄露又有區(qū)別,待會我會細講的,堆溢出我們怎么去解決,你們基本上都遇到過堆溢出沒有,堆溢出,就是申請的空間不足了,把內(nèi)存空間加大一點就行了,這個時候我就來演示一把
package com.learn.test;import java.util.ArrayList;
import java.util.List;/*** 內(nèi)存溢出問題* 初始化加載的比較多* 我開始做Spring項目的時候* 我剛學(xué)JAVA的時候* 做SSH進行整合的時候* 報了一個內(nèi)存溢出* 去百度找方案* 加內(nèi)存* 那時候還沒有學(xué)JVM* 為什么加堆內(nèi)存大小能解決問題* 學(xué)JVM的時候才知道整個原理* 電腦只有2個G的內(nèi)存* 經(jīng)常做Spring項目的時候* 經(jīng)常會發(fā)生內(nèi)存溢出的問題* 電腦根本跑不起一些項目* 這個會出現(xiàn)內(nèi)存溢出的問題* 怎么去演示* 這段代碼至少需要幾兆的空間* 這段代碼執(zhí)行至少需要幾兆內(nèi)存的空間大小* 至少10M是不是* 你們覺得配多少合適呢* 有的人說配10M* 配10M肯定是不行的* 因為它可能會被其他的地方占用空間嗎* 所以10M肯定不行的* 我在這里配置10M看一下* -Xms1m -Xmx10m -XX:+PrintGCDetails -XX:+HeapDumpOnOutOfMemoryError* 這里我的堆的初始值是1M* 然后最大是10M* 你會發(fā)現(xiàn)10M肯定是會有問題的* 先運行一遍* 默認是可以的,* 因為默認值很大* 默認是4G內(nèi)存* -Xms1m -Xmx10m -XX:+PrintGCDetails -XX:+HeapDumpOnOutOfMemoryError* 我們配置這個* 初始值是1M* 最大值是10M* 完全不夠* [Full GC (Allocation Failure) * 而且這個時候有Full GC* Full GC表示什么目的* 如果你老年代的都不足的情況下,* 方法區(qū)的內(nèi)存不足的情況下* 或者老年代快滿的情況下* 它會做一個全部的回收* 把新生代和老年代都回收一下* 為什么呢* 你們在做開發(fā)的時候會遇到的* 如果你們項目中內(nèi)存溢出的時候* 他首先會做一個Full GC的處理* 目的是什么呢* 就是把整個新生代和老年代的空間都給你回收一遍* 看有沒有可回收的* [GC (Allocation Failure)* 整個GC是什么GC* 是Minor GC嗎* 一般只要發(fā)生Full GC就會發(fā)生Minor GC* 10M肯定不夠* 我們再改一下* 比如15M* -Xms1m -Xmx15m -XX:+PrintGCDetails -XX:+HeapDumpOnOutOfMemoryError* 15M也不一定* -Xms1m -Xmx20m -XX:+PrintGCDetails -XX:+HeapDumpOnOutOfMemoryError* 我們改20M* 20M也不夠* 那我們到底設(shè)置多少M合適* 我們設(shè)置100M* -Xms5m -Xmx100m -XX:+PrintGCDetails -XX:+HeapDumpOnOutOfMemoryError* 100M綽綽有余* 而且你們有沒有發(fā)現(xiàn)問題* 當我最大的內(nèi)存設(shè)置的比較大的情況下* GC回收是不是不會很頻繁* 你們看到效果沒有* 剛才如果我們設(shè)置10M,20M的話* 至少4次Minor的GC* 發(fā)生兩次Full GC* 如果我把最大內(nèi)存配置為100M的時候* 那他只發(fā)生1次的新生代的回收* -Xms5m -Xmx50m -XX:+PrintGCDetails -XX:+HeapDumpOnOutOfMemoryError* 我們改成50M* i:8* 運行到第8次的時候,* 50M都不夠* 會有Full GC* 我估計還是配100M* * * @author Leon.Sun**/
public class Test0004 {public static void main(String[] args) {/*** ArrayList數(shù)組其實也是有空間的* ArrayList底層是數(shù)組* 也是會占空間的* 最大內(nèi)存值是50M* 這個時候是不是就夠了*/
// List<Object> listObject = new ArrayList<>();for (int i = 0; i < 10; i++) {System.out.println("i:" + i);Byte[] bytes = new Byte[1 * 1024 * 1024];/*** 看到效果沒有* 你們在開發(fā)中定義的list其實是非常占內(nèi)存的* 我把list注掉之后就沒有很多內(nèi)存了* [GC (Allocation Failure) [PSYoungGen* 這個GC是什么GC* 是回收新生代還是回收老年代* 記住這是新生代回收* [Full GC (Allocation Failure)* 這個是新生代和老年代一起回收* 他們到底有什么樣的區(qū)別* 有一些細節(jié)參數(shù)先不講* [PSYoungGen: 480K->0K(1536K)] [ParOldGen: 33008K->1017K(4096K)]* 他已經(jīng)打印出日志了* 今天還沒有細分日志的分析* 我們下節(jié)課詳細分析* [GC (Allocation Failure) [PSYoungGen: 496K->480K(1536K)]* 這個是新生代的日志打印* [Full GC (Allocation Failure) [PSYoungGen: 480K->0K(1536K)] * 這個是新生代和老年代的日志打印* PSYoungGen這是新生代* ParOldGen這是老年代* 這個為什么要回收* 你可以看一下我是怎么配的* -Xms1m -Xmx50m -XX:+PrintGCDetails -XX:+HeapDumpOnOutOfMemoryError* 初始值是1兆內(nèi)存* 因為初始值非常小* 你這里要用10個1M內(nèi)存* 他需要不停的去回收垃圾* 重新申請內(nèi)存出來* 就是內(nèi)存不夠的情況下需要去回收垃圾的* 你如果越大的情況下就不會有這些GC日志信息的* 如果我初始值改成50M* -Xms50m -Xmx50m -XX:+PrintGCDetails -XX:+HeapDumpOnOutOfMemoryError* 你們可以數(shù)一下一共有多少次GC日志* 剛開始是4次,* 現(xiàn)在只要3次* 如果空間非常足* 我就沒有必要去回收了* 我內(nèi)存不足的情況下我再去回收* 垃圾回收的基本原則* 垃圾回收機制基本原則:內(nèi)存不足的時候回去回收,內(nèi)存如果足夠,暫時不會區(qū)回收。 減少回收次數(shù)和回收的時間* 因為垃圾回收會對其他的工作線程會有影響的* 就是會暫停一下* 你如果經(jīng)常頻繁的去回收* 非常影響我整個程序的* 你們會發(fā)現(xiàn)在生產(chǎn)環(huán)境服務(wù)器* 一般內(nèi)存都特別大* 都是8個G,16G* 如果內(nèi)存夠就不會發(fā)生垃圾回收* 如果內(nèi)存非常小垃圾回收就會頻繁的去回收* 會非常影響你整個程序的* 回收原則就是減少回收的次數(shù)和回收時間* */
// listObject.add(bytes);}System.out.println("添加成功...");}
}
?
總結(jié)
以上是生活随笔為你收集整理的jvm解决堆内存溢出问题的全部內(nèi)容,希望文章能夠幫你解決所遇到的問題。
- 上一篇: 设置新生代与老年代比例关系
- 下一篇: 栈溢出