欧美bbbwbbbw肥妇,免费乱码人妻系列日韩,一级黄片

JVM調(diào)優(yōu)OutOfMemoryError異常分析

 更新時(shí)間:2022年11月03日 11:49:15   作者:賈子杰  
這篇文章主要為大家介紹了JVM調(diào)優(yōu)OutOfMemoryError異常分析,有需要的朋友可以借鑒參考下,希望能夠有所幫助,祝大家多多進(jìn)步,早日升職加薪

1.Java 堆溢出

1.1 設(shè)置JVM參數(shù)

-verbose:gc -Xms20M -Xmx20M -Xmn10M  -XX:+PrintGC -XX:+PrintGCDetails -XX:+HeapDumpOnOutOfMemoryError -XX:SurvivorRatio=8

  • -Xmx20m:設(shè)置JVM最大可用內(nèi)存為20M。
  • -Xms20m:設(shè)置JVM促使內(nèi)存為20m。此值可以設(shè)置與-Xmx相同,以避免每次垃圾回收完成后JVM重新分配內(nèi)
  • -Xmn10m:設(shè)置年輕代大小為10m
  • -XX:SurvivorRatio=8 Eden區(qū)和Survivor區(qū)間比例是8:1, 所以分配一下就是 eden8m, fromspace 1m, to space1m 加起來(lái)10m

1.2 測(cè)試代碼

package com.jzj.jvmtest.oomtest;
import java.util.ArrayList;
import java.util.List;
/**
 * 堆溢出, 只要不停的新建對(duì)象,就會(huì)堆溢出
 */
public class HeapOOM {
    public static void main(String[] args) {
        System.out.print("最大內(nèi)存: ");
        System.out.println(Runtime.getRuntime().maxMemory() / 1024 / 1024 + "MB");
        System.out.print("可用內(nèi)存: ");
        System.out.println(Runtime.getRuntime().freeMemory() / 1024 / 1024 + "MB");
        System.out.print("已使用內(nèi)存: ");
        System.out.println(Runtime.getRuntime().totalMemory() / 1024 / 1024 + "MB");
        List<HeapOOM> list = new ArrayList<>();
        while (true) {
            list.add(new HeapOOM());
        }
    }
}

1.3 運(yùn)行OOM日志

可以看到 日志 java.lang.OutOfMemoryError: Java heap space Heap Space 就是堆溢出

最大內(nèi)存: 19MB
可用內(nèi)存: 16MB
已使用內(nèi)存: 19MB
[GC (Allocation Failure) [PSYoungGen: 8192K->1000K(9216K)] 8192K->4533K(19456K), 0.0044438 secs] [Times: user=0.00 sys=0.00, real=0.01 secs] 
[GC (Allocation Failure) --[PSYoungGen: 9192K->9192K(9216K)] 12725K->19427K(19456K), 0.0091278 secs] [Times: user=0.11 sys=0.00, real=0.01 secs] 
[Full GC (Ergonomics) [PSYoungGen: 9192K->0K(9216K)] [ParOldGen: 10235K->10221K(10240K)] 19427K->10221K(19456K), [Metaspace: 3495K->3495K(1056768K)], 0.1549254 secs] [Times: user=0.69 sys=0.02, real=0.16 secs] 
[Full GC (Ergonomics) [PSYoungGen: 8192K->7167K(9216K)] [ParOldGen: 10221K->8971K(10240K)] 18413K->16138K(19456K), [Metaspace: 3496K->3496K(1056768K)], 0.1722236 secs] [Times: user=1.30 sys=0.00, real=0.17 secs] 
[Full GC (Ergonomics) [PSYoungGen: 7652K->7604K(9216K)] [ParOldGen: 8971K->8971K(10240K)] 16624K->16575K(19456K), [Metaspace: 3496K->3496K(1056768K)], 0.1296002 secs] [Times: user=1.25 sys=0.00, real=0.13 secs] 
[Full GC (Allocation Failure) [PSYoungGen: 7604K->7604K(9216K)] [ParOldGen: 8971K->8953K(10240K)] 16575K->16557K(19456K), [Metaspace: 3496K->3496K(1056768K)], 0.1372692 secs] [Times: user=1.27 sys=0.00, real=0.14 secs] 
java.lang.OutOfMemoryError: Java heap space
Dumping heap to java_pid28084.hprof ...
Heap dump file created [28363283 bytes in 0.058 secs]
Heap
 PSYoungGen      total 9216K, used 7794K [0x00000000ff600000, 0x0000000100000000, 0x0000000100000000)
  eden space 8192K, 95% used [0x00000000ff600000,0x00000000ffd9c8a8,0x00000000ffe00000)
  from space 1024K, 0% used [0x00000000ffe00000,0x00000000ffe00000,0x00000000fff00000)
  to   space 1024K, 0% used [0x00000000fff00000,0x00000000fff00000,0x0000000100000000)
 ParOldGen       total 10240K, used 8953K [0x00000000fec00000, 0x00000000ff600000, 0x00000000ff600000)
  object space 10240K, 87% used [0x00000000fec00000,0x00000000ff4be5a0,0x00000000ff600000)
 Metaspace       used 3527K, capacity 4500K, committed 4864K, reserved 1056768K
  class space    used 385K, capacity 388K, committed 512K, reserved 1048576K
Exception in thread "main" java.lang.OutOfMemoryError: Java heap space
    at java.util.Arrays.copyOf(Arrays.java:3210)
    at java.util.Arrays.copyOf(Arrays.java:3181)
    at java.util.ArrayList.grow(ArrayList.java:265)
    at java.util.ArrayList.ensureExplicitCapacity(ArrayList.java:239)
    at java.util.ArrayList.ensureCapacityInternal(ArrayList.java:231)
    at java.util.ArrayList.add(ArrayList.java:462)
    at com.jzj.jvmtest.oomtest.HeapOOM.main(HeapOOM.java:20)

Process finished with exit code 1

2.Java棧、本地方法棧溢出

2.1 設(shè)置JVM參數(shù)

-verbose:gc -Xms20M -Xmx20M -Xmn10M  -XX:+PrintGC -XX:+PrintGCDetails -XX:+HeapDumpOnOutOfMemoryError -XX:SurvivorRatio=8  -Xss128k

這次最后加了一個(gè)-Xss 設(shè)置每個(gè)線程的堆棧大小

  • 虛擬機(jī)擴(kuò)展棧時(shí),如果棧深度大于虛擬機(jī)允許最大深度,就會(huì)出現(xiàn)StackOverflowError異常
  • 如果在擴(kuò)展棧時(shí),需要的內(nèi)存空間不夠,那么就會(huì)出現(xiàn)OutOfMemoryError 就是OOM異常

2.2 測(cè)試代碼

package com.jzj.jvmtest.oomtest;
/**
 * 棧溢出, 只要不停的新建對(duì)象,循環(huán)遞歸,超出棧容量限制就會(huì)OOM
 * 
 * 1.棧深入超出限制,stackOverflowError
 * 2.棧擴(kuò)展時(shí)候,內(nèi)存不夠,導(dǎo)致OOM異常
 */
public class StackOOM {
    /**
     * 初始化棧的深度
     */
    private int stackLength = 1;
    /**
     * 循環(huán)去增加棧的深度
     */
    public void stackLeak() {
        stackLength++;
        stackLeak();
    }
    public static void main(String[] args) {
        System.out.print("最大內(nèi)存: ");
        System.out.println(Runtime.getRuntime().maxMemory() / 1024 / 1024 + "MB");
        System.out.print("可用內(nèi)存: ");
        System.out.println(Runtime.getRuntime().freeMemory() / 1024 / 1024 + "MB");
        System.out.print("已使用內(nèi)存: ");
        System.out.println(Runtime.getRuntime().totalMemory() / 1024 / 1024 + "MB");
        StackOOM oom = new StackOOM();
        try {
            oom.stackLeak();
        } catch (Throwable e) {
            System.out.println("stack length ============" + oom.stackLength);
            throw e;
        }
    }
}

2.3 運(yùn)行OOM日志

可以看到 日志Exception in thread "main" java.lang.StackOverflowError StackOverflowError 就是虛擬機(jī)棧 ,可以看到棧深度在995的時(shí)候就發(fā)生了異常,超出了虛擬機(jī)棧的深度,拋出異常

最大內(nèi)存: 19MB
可用內(nèi)存: 16MB
已使用內(nèi)存: 19MB
stack length ============995
Heap
 PSYoungGen      total 9216K, used 4158K [0x00000000ff600000, 0x0000000100000000, 0x0000000100000000)
  eden space 8192K, 50% used [0x00000000ff600000,0x00000000ffa0fae8,0x00000000ffe00000)
  from space 1024K, 0% used [0x00000000fff00000,0x00000000fff00000,0x0000000100000000)
  to   space 1024K, 0% used [0x00000000ffe00000,0x00000000ffe00000,0x00000000fff00000)
 ParOldGen       total 10240K, used 0K [0x00000000fec00000, 0x00000000ff600000, 0x00000000ff600000)
  object space 10240K, 0% used [0x00000000fec00000,0x00000000fec00000,0x00000000ff600000)
 Metaspace       used 3558K, capacity 4500K, committed 4864K, reserved 1056768K
  class space    used 385K, capacity 388K, committed 512K, reserved 1048576K
Exception in thread "main" java.lang.StackOverflowError
    at com.jzj.jvmtest.oomtest.StackOOM.stackLeak(StackOOM.java:19)
    at com.jzj.jvmtest.oomtest.StackOOM.stackLeak(StackOOM.java:20)
    at com.jzj.jvmtest.oomtest.StackOOM.stackLeak(StackOOM.java:20)
    at com.jzj.jvmtest.oomtest.StackOOM.stackLeak(StackOOM.java:20)
    at com.jzj.jvmtest.oomtest.StackOOM.main(StackOOM.java:34)

Process finished with exit code 1

2.4 Java虛擬機(jī)OOM異常

理論上要想虛擬機(jī)棧拋出OOM,在多線程的情況下,可以不停的新建線程來(lái)實(shí)現(xiàn)OOM

但是這樣 通過(guò)多個(gè)線程創(chuàng)建的OOM異常和??臻g是否足夠大沒(méi)有直接關(guān)系? 準(zhǔn)確來(lái)說(shuō)為每個(gè)線程棧分配的空間越大,反而越容易長(zhǎng)身OOM why? 為什么 為每個(gè)線程分配的空間越大,越容易OOM呢?

分析:

  • 假設(shè)操作系統(tǒng)有2G內(nèi)存
  • 虛擬機(jī)可以通過(guò)參數(shù)來(lái)控制虛擬機(jī)堆 和 方法區(qū)允許內(nèi)存的最大值
  • 堆最大值 -Xmx 控制,方法區(qū)永久區(qū) -MaxPermSize最大方法區(qū)容量控制方法區(qū)大小
  • 2GB 減去 堆大小, 減去 方法區(qū)大小, 剩下的內(nèi)存就由 java 虛擬機(jī)棧與本地方法棧共享瓜分
  • 每個(gè)線程分配的空間越大, 那么系統(tǒng)可以操作的線程數(shù)就越少,那么新建線程就越容易超標(biāo),造成OOM

!!!!!!!! 為什么在這里我不代碼演示一下創(chuàng)建線程導(dǎo)致oom

因?yàn)镴ava的線程時(shí)映射到操作系統(tǒng)內(nèi)核線程上的,你創(chuàng)建多的線程,執(zhí)行這種代碼,容易造成操作系統(tǒng)假死,電腦死機(jī),所以謹(jǐn)慎操作,這里就不演示這種OOM了

3.Java 運(yùn)行常量池溢出

3.1 設(shè)置JVM參數(shù)-注意區(qū)分jdk版本

-verbose:gc -Xms20M -Xmx20M -Xmn10M  -XX:+PrintGC -XX:+PrintGCDetails -XX:+HeapDumpOnOutOfMemoryError -XX:SurvivorRatio=8 -XX:PermSize=5M -XX:MaxPermSize=5M

這里新加了參數(shù) -XX:PermSize=5M -XX:MaxPermSize=5M 來(lái)控制方法區(qū)大小

  • -XX:PermSize=5M:設(shè)置方法區(qū)大小。1.6JDK
  • -XX:MaxPermSize=5M:設(shè)置方法區(qū)最大值。1.6JDK

!!!!!! 注意 這個(gè)測(cè)試方法用的是 String.valueOf(i++).intern() 這個(gè)方法 在jdk 1.6沒(méi)問(wèn)題, 是能夠拋出 PermSpace OOM的 因?yàn)?/p>

  • 在 JDK 1.6 及之前的版本中,由于常量池分配在永久代內(nèi),我們可以通過(guò) -XX:PermSize 和 -XX:MaxPermSize 限制方法區(qū)大小,從而間接限制其中常量池的容量
  • 但是 在 JDK1.8運(yùn)行這段程序不會(huì)得到相同的結(jié)果,而是出現(xiàn)以下的提示信息,這是因?yàn)檫@兩個(gè)參數(shù)已經(jīng)不在JDK1.7中使用了。
  • 提示錯(cuò)誤 Java HotSpot(TM) 64-Bit Server VM warning: ignoring option PermSize=5M; support was removed in 8.0
  • 提示錯(cuò)誤 Java HotSpot(TM) 64-Bit Server VM warning: ignoring option MaxPermSize=5M; support was removed in 8.0

不同的版本 ,這段代碼拋出不同的異常

VM Args(jdk1.6): -XX:PermSize=10M -XX:MaxPermSize=10M

VM Args(jdk1.7): -Xms10m -Xmx10m -XX:+HeapDumpOnOutOfMemoryError

VM Args (jdk1.8) : -XX:MetaspaceSize=10m -XX:MaxMetaspaceSize=10m

Exception(jdk1.6) : java.lang.OutOfMemoryError: PermGen space

Exception(jdk1.7): java.lang.OutOfMemoryError: Java heap space

Exception(jdk1.8): java.lang.OutOfMemoryError: GC overhead limit exceeded

3.2 測(cè)試代碼

所以 為了在1.8的jdk中 ,測(cè)試常量池溢出 ,我們?cè)撊绾文M呢? jdk1.8 使用元空間( Metaspace )替代了永久代( PermSize ),因此我們可以在 1.8 中指定 Metaspace 的大小模擬 測(cè)試

!!!! JDK1.8這里新加了參數(shù) 來(lái)控制方法區(qū)大小

  • -XX:MetaspaceSize=5m,初始空間大小,達(dá)到該值就會(huì)觸發(fā)垃圾收集進(jìn)行類型卸載,同時(shí)GC會(huì)對(duì)該值進(jìn)行調(diào)整:如果釋放了大量的空間,
  • -XX:MaxMetaspaceSize=5m,最大空間,默認(rèn)是沒(méi)有限制的。
/**
 * 設(shè)置方法區(qū)及常量池 OOM溢出
 * 方法區(qū)中運(yùn)行時(shí)常量池溢出
 * VM Args(jdk1.6): -XX:PermSize=10M -XX:MaxPermSize=10M
 * VM Args(jdk1.7): -Xms30m -Xmx30m -XX:+HeapDumpOnOutOfMemoryError
 * VM Args (jdk1.8) :  -XX:MetaspaceSize=10m  -XX:MaxMetaspaceSize=10m
 * Exception(jdk1.6) : java.lang.OutOfMemoryError: PermGen space
 * Exception(jdk1.7): java.lang.OutOfMemoryError: Java heap space
 * Exception(jdk1.8): java.lang.OutOfMemoryError: GC overhead limit exceeded
 */
public class ConstantOOM {
    public static void main(String[] args) {
        System.out.print("最大內(nèi)存: ");
        System.out.println(Runtime.getRuntime().maxMemory() / 1024 / 1024 + "MB");
        System.out.print("可用內(nèi)存: ");
        System.out.println(Runtime.getRuntime().freeMemory() / 1024 / 1024 + "MB");
        System.out.print("已使用內(nèi)存: ");
        System.out.println(Runtime.getRuntime().totalMemory() / 1024 / 1024 + "MB");
        //使用List ,保持常量池的使用, 避免FullGC回收常量池的行為
        List<String> staticList = new ArrayList<>();
        //5M的PermSize  讓List for循環(huán)添加變量 讓常量池瘋狂的添加新的對(duì)象
        long i = 0L;
        while (true) {
            //使用 String.intern 調(diào)用”ab”.intern()方法的時(shí)候會(huì)返回”ab“
            // 但是這個(gè)方法會(huì)首先檢查字符串池中是否有”ab”這個(gè)字符串,如果存在則返回這個(gè)字符串的引用
            // 否則就將這個(gè)字符串添加到字符串池中,然會(huì)返回這個(gè)字符串的引用
            staticList.add(String.valueOf(i++).intern());
        }
    }
}

3.3 運(yùn)行OOM日志

可以看到 日志 Exception in thread "main" java.lang.OutOfMemoryError: GC overhead limit exceeded 并不是 MetaSpace OOM的日志, 所以 JDK1.8中 ,上面的 代碼是沒(méi)法實(shí)現(xiàn) 元空間的內(nèi)存溢出的

最大內(nèi)存: 19MB
可用內(nèi)存: 16MB
已使用內(nèi)存: 19MB
[GC (Allocation Failure) [PSYoungGen: 8192K->1016K(9216K)] 8192K->5564K(19456K), 0.0041671 secs] [Times: user=0.00 sys=0.00, real=0.00 secs] 
[GC (Allocation Failure) --[PSYoungGen: 9208K->9208K(9216K)] 13756K->19446K(19456K), 0.0086760 secs] [Times: user=0.01 sys=0.00, real=0.01 secs] 
[Full GC (Ergonomics) [PSYoungGen: 9208K->2482K(9216K)] [ParOldGen: 10237K->10179K(10240K)] 19446K->12662K(19456K), [Metaspace: 3497K->3497K(1056768K)], 0.1127624 secs] [Times: user=0.41 sys=0.00, real=0.11 secs] 
[Full GC (Ergonomics) [PSYoungGen: 8192K->7167K(9216K)] [ParOldGen: 10179K->10165K(10240K)] 18371K->17332K(19456K), [Metaspace: 3498K->3498K(1056768K)], 0.1072663 secs] [Times: user=0.63 sys=0.00, real=0.11 secs] 
......
[Full GC (Ergonomics) [PSYoungGen: 8192K->8192K(9216K)] [ParOldGen: 10199K->10199K(10240K)] 18391K->18391K(19456K), [Metaspace: 3502K->3502K(1056768K)], 0.0641831 secs] [Times: user=0.63 sys=0.00, real=0.06 secs] 
[Full GC (Ergonomics) [PSYoungGen: 8192K->8192K(9216K)] [ParOldGen: 10201K->10201K(10240K)] 18393K->18393K(19456K), [Metaspace: 3502K->3502K(1056768K)], 0.0631814 secs] [Times: user=0.48 sys=0.00, real=0.06 secs] 
[Full GC (Ergonomics) [PSYoungGen: 8192K->8192K(9216K)] [ParOldGen: 10202K->10202K(10240K)] 18394K->18394K(19456K), [Metaspace: 3502K->3502K(1056768K)], 0.0626523 secs] [Times: user=0.48 sys=0.00, real=0.06 secs] 
java.lang.OutOfMemoryError: GC overhead limit exceeded
Dumping heap to java_pid10140.hprof ...
Heap dump file created [24293672 bytes in 0.065 secs]
[Full GC (Ergonomics) [PSYoungGen: 8192K->0K(9216K)] [ParOldGen: 10238K->763K(10240K)] 18430K->763K(19456K), [Metaspace: 3522K->3522K(1056768K)], 0.0068815 secs] [Times: user=0.16 sys=0.00, real=0.01 secs] 
Heap
 PSYoungGen      total 9216K, used 273K [0x00000000ff600000, 0x0000000100000000, 0x0000000100000000)
  eden space 8192K, 3% used [0x00000000ff600000,0x00000000ff6444e0,0x00000000ffe00000)
  from space 1024K, 0% used [0x00000000ffe00000,0x00000000ffe00000,0x00000000fff00000)
  to   space 1024K, 0% used [0x00000000fff00000,0x00000000fff00000,0x0000000100000000)
 ParOldGen       total 10240K, used 763K [0x00000000fec00000, 0x00000000ff600000, 0x00000000ff600000)
  object space 10240K, 7% used [0x00000000fec00000,0x00000000fecbeca8,0x00000000ff600000)
 Metaspace       used 3616K, capacity 4540K, committed 4864K, reserved 1056768K
  class space    used 394K, capacity 428K, committed 512K, reserved 1048576K
Exception in thread "main" java.lang.OutOfMemoryError: GC overhead limit exceeded
    at java.lang.Integer.toString(Integer.java:403)
    at java.lang.String.valueOf(String.java:3099)
    at com.jzj.jvmtest.oomtest.PermOOM.main(PermOOM.java:28)
Java HotSpot(TM) 64-Bit Server VM warning: ignoring option PermSize=5M; support was removed in 8.0
Java HotSpot(TM) 64-Bit Server VM warning: ignoring option MaxPermSize=5M; support was removed in 8.0

Process finished with exit code 1

4.Java 方法區(qū)溢出-jdk8

4.1 設(shè)置JVM參數(shù)

所以 為了在1.8的jdk中 ,測(cè)試方法區(qū)溢出 ,我們?cè)撊绾文M呢? jdk1.8 使用元空間( Metaspace )替代了永久代( PermSize ),因此我們可以在 1.8 中指定 Metaspace 的大小模擬 測(cè)試,我們用

!!!! JDK1.8這里新加了參數(shù) 來(lái)控制方法區(qū)大小

  • -XX:MetaspaceSize=5m,初始空間大小,達(dá)到該值就會(huì)觸發(fā)垃圾收集進(jìn)行類型卸載,同時(shí)GC會(huì)對(duì)該值進(jìn)行調(diào)整:如果釋放了大量的空間,
  • -XX:MaxMetaspaceSize=5m,最大空間,默認(rèn)是沒(méi)有限制的。

-verbose:gc -Xms20M -Xmx20M -Xmn10M  -XX:+PrintGC -XX:+PrintGCDetails -XX:+HeapDumpOnOutOfMemoryError -XX:MetaspaceSize=10m -XX:MaxMetaspaceSize=10m

這里新加了參數(shù) -XX:MetaspaceSize=10M -XX:MaxMetaspaceSize=10M 來(lái)控制方法區(qū)大小

  • -XX:MetaspaceSize=10m,初始空間大小,達(dá)到該值就會(huì)觸發(fā)垃圾收集進(jìn)行類型卸載,同時(shí)GC會(huì)對(duì)該值進(jìn)行調(diào)整:如果釋放了大量的空間,
  • -XX:MaxMetaspaceSize=10m,最大空間,默認(rèn)是沒(méi)有限制的。

方法區(qū)存的什么? 類信息,常量,靜態(tài)變量,我們就用CGLib 代理來(lái)創(chuàng)建類,使得方法區(qū)內(nèi)存溢出

4.2 測(cè)試代碼

package com.jzj.jvmtest.oomtest;
import org.springframework.cglib.proxy.Enhancer;
import org.springframework.cglib.proxy.MethodInterceptor;
/**
 * 方法區(qū) 內(nèi)存溢出,方法區(qū)存放的是 類,靜態(tài)常量,變量信息
 * 所以 我們就用CGLIB 瘋狂的創(chuàng)建類 就可以達(dá)到OOM了
 */
public class MethodAreaOOM extends ClassLoader {
    public static void main(String[] args) {
        System.out.print("最大內(nèi)存: ");
        System.out.println(Runtime.getRuntime().maxMemory() / 1024 / 1024 + "MB");
        System.out.print("可用內(nèi)存: ");
        System.out.println(Runtime.getRuntime().freeMemory() / 1024 / 1024 + "MB");
        System.out.print("已使用內(nèi)存: ");
        System.out.println(Runtime.getRuntime().totalMemory() / 1024 / 1024 + "MB");
        int count = 0;
        try {
            for (int i = 0; i < 10000; i++) {
                Enhancer enhancer = new Enhancer();
                enhancer.setSuperclass(MethodAreaOOM.class);
                enhancer.setUseCache(false);
                enhancer.setCallback((MethodInterceptor) (o, method, objects, methodProxy) -> methodProxy.invokeSuper(o, args));
                //cglib 創(chuàng)建類文件
                enhancer.create();
                count = i;
            }
        } catch (Throwable e) {
            System.out.println("****count=" + count);
            e.printStackTrace();
        }
    }
}

4.3 運(yùn)行OOM日志

可以看到 日志java.lang.OutOfMemoryError: Metaspace 就是員工間方法區(qū)的OOM 溢出

"C:\Program Files\Java\jdk1.8.0_181\bin\java.exe" -verbose:gc -Xms20M -Xmx20M -Xmn10M -XX:+PrintGC -XX:+PrintGCDetails -XX:+HeapDumpOnOutOfMemoryError -XX:MetaspaceSize=10m -XX:MaxMetaspaceSize=10m "-javaagent:E:\Program Files\JetBrains\IntelliJ IDEA 2019.3.4\lib\idea_rt.jar=59628:E:\Program Files\JetBrains\IntelliJ IDEA 2019.3.4\bin" -Dfile.encoding=UTF-8 -classpath "C:\Program Files\Java\jdk1.8.0_181\jre\lib\charsets.jar;C:\Program Files\Java\jdk1.8.0_181\jre\lib\deploy.jar;C:\Program Files\Java\jdk1.8.0_181\jre\lib\ext\access-bridge-64.jar;C:\Program Files\Java\jdk1.8.0_181\jre\lib\ext\cldrdata.jar;C:\Program Files\Java\jdk1.8.0_181\jre\lib\ext\dnsns.jar;C:\Program Files\Java\jdk1.8.0_181\jre\lib\ext\jaccess.jar;C:\Program Files\Java\jdk1.8.0_181\jre\lib\ext\jfxrt.jar;C:\Program Files\Java\jdk1.8.0_181\jre\lib\ext\localedata.jar;C:\Program Files\Java\jdk1.8.0_181\jre\lib\ext\nashorn.jar;C:\Program Files\Java\jdk1.8.0_181\jre\lib\ext\sunec.jar;C:\Program Files\Java\jdk1.8.0_181\jre\lib\ext\sunjce_provider.jar;C:\Program Files\Java\jdk1.8.0_181\jre\lib\ext\sunmscapi.jar;C:\Program Files\Java\jdk1.8.0_181\jre\lib\ext\sunpkcs11.jar;C:\Program Files\Java\jdk1.8.0_181\jre\lib\ext\zipfs.jar;C:\Program Files\Java\jdk1.8.0_181\jre\lib\javaws.jar;C:\Program Files\Java\jdk1.8.0_181\jre\lib\jce.jar;C:\Program Files\Java\jdk1.8.0_181\jre\lib\jfr.jar;C:\Program Files\Java\jdk1.8.0_181\jre\lib\jfxswt.jar;C:\Program Files\Java\jdk1.8.0_181\jre\lib\jsse.jar;C:\Program Files\Java\jdk1.8.0_181\jre\lib\management-agent.jar;C:\Program Files\Java\jdk1.8.0_181\jre\lib\plugin.jar;C:\Program Files\Java\jdk1.8.0_181\jre\lib\resources.jar;C:\Program Files\Java\jdk1.8.0_181\jre\lib\rt.jar;E:\myworkspace\distribute\jvmtest\target\classes;E:\MavenRepository\org\springframework\boot\spring-boot-starter-web\2.5.4\spring-boot-starter-web-2.5.4.jar;E:\MavenRepository\org\springframework\boot\spring-boot-starter\2.5.4\spring-boot-starter-2.5.4.jar;E:\MavenRepository\org\springframework\boot\spring-boot\2.5.4\spring-boot-2.5.4.jar;E:\MavenRepository\org\springframework\boot\spring-boot-autoconfigure\2.5.4\spring-boot-autoconfigure-2.5.4.jar;E:\MavenRepository\org\springframework\boot\spring-boot-starter-logging\2.5.4\spring-boot-starter-logging-2.5.4.jar;E:\MavenRepository\ch\qos\logback\logback-classic\1.2.5\logback-classic-1.2.5.jar;E:\MavenRepository\ch\qos\logback\logback-core\1.2.5\logback-core-1.2.5.jar;E:\MavenRepository\org\apache\logging\log4j\log4j-to-slf4j\2.14.1\log4j-to-slf4j-2.14.1.jar;E:\MavenRepository\org\apache\logging\log4j\log4j-api\2.14.1\log4j-api-2.14.1.jar;E:\MavenRepository\org\slf4j\jul-to-slf4j\1.7.32\jul-to-slf4j-1.7.32.jar;E:\MavenRepository\jakarta\annotation\jakarta.annotation-api\1.3.5\jakarta.annotation-api-1.3.5.jar;E:\MavenRepository\org\yaml\snakeyaml\1.28\snakeyaml-1.28.jar;E:\MavenRepository\org\springframework\boot\spring-boot-starter-json\2.5.4\spring-boot-starter-json-2.5.4.jar;E:\MavenRepository\com\fasterxml\jackson\core\jackson-databind\2.12.4\jackson-databind-2.12.4.jar;E:\MavenRepository\com\fasterxml\jackson\core\jackson-annotations\2.12.4\jackson-annotations-2.12.4.jar;E:\MavenRepository\com\fasterxml\jackson\core\jackson-core\2.12.4\jackson-core-2.12.4.jar;E:\MavenRepository\com\fasterxml\jackson\datatype\jackson-datatype-jdk8\2.12.4\jackson-datatype-jdk8-2.12.4.jar;E:\MavenRepository\com\fasterxml\jackson\datatype\jackson-datatype-jsr310\2.12.4\jackson-datatype-jsr310-2.12.4.jar;E:\MavenRepository\com\fasterxml\jackson\module\jackson-module-parameter-names\2.12.4\jackson-module-parameter-names-2.12.4.jar;E:\MavenRepository\org\springframework\boot\spring-boot-starter-tomcat\2.5.4\spring-boot-starter-tomcat-2.5.4.jar;E:\MavenRepository\org\apache\tomcat\embed\tomcat-embed-core\9.0.52\tomcat-embed-core-9.0.52.jar;E:\MavenRepository\org\apache\tomcat\embed\tomcat-embed-el\9.0.52\tomcat-embed-el-9.0.52.jar;E:\MavenRepository\org\apache\tomcat\embed\tomcat-embed-websocket\9.0.52\tomcat-embed-websocket-9.0.52.jar;E:\MavenRepository\org\springframework\spring-web\5.3.9\spring-web-5.3.9.jar;E:\MavenRepository\org\springframework\spring-beans\5.3.9\spring-beans-5.3.9.jar;E:\MavenRepository\org\springframework\spring-webmvc\5.3.9\spring-webmvc-5.3.9.jar;E:\MavenRepository\org\springframework\spring-aop\5.3.9\spring-aop-5.3.9.jar;E:\MavenRepository\org\springframework\spring-context\5.3.9\spring-context-5.3.9.jar;E:\MavenRepository\org\springframework\spring-expression\5.3.9\spring-expression-5.3.9.jar;E:\MavenRepository\org\slf4j\slf4j-api\1.7.32\slf4j-api-1.7.32.jar;E:\MavenRepository\org\springframework\spring-core\5.3.9\spring-core-5.3.9.jar;E:\MavenRepository\org\springframework\spring-jcl\5.3.9\spring-jcl-5.3.9.jar" com.jzj.jvmtest.oomtest.MethodAreaOOM
最大內(nèi)存: 19MB
可用內(nèi)存: 16MB
已使用內(nèi)存: 19MB
[GC (Allocation Failure) [PSYoungGen: 8192K->1000K(9216K)] 8192K->1709K(19456K), 0.0013246 secs] [Times: user=0.00 sys=0.00, real=0.00 secs] 
[GC (Allocation Failure) [PSYoungGen: 9192K->1000K(9216K)] 9901K->2255K(19456K), 0.0011901 secs] [Times: user=0.00 sys=0.00, real=0.00 secs] 
...
[Full GC (Metadata GC Threshold) [PSYoungGen: 320K->0K(8192K)] [ParOldGen: 5896K->3747K(10240K)] 6216K->3747K(18432K), [Metaspace: 10049K->10049K(1058816K)], 0.0380225 secs] [Times: user=0.28 sys=0.00, real=0.04 secs] 
[GC (Last ditch collection) [PSYoungGen: 0K->0K(8192K)] 3747K->3747K(18432K), 0.0003694 secs] [Times: user=0.00 sys=0.00, real=0.00 secs] 
[Full GC (Last ditch collection) [PSYoungGen: 0K->0K(8192K)] [ParOldGen: 3747K->2210K(10240K)] 3747K->2210K(18432K), [Metaspace: 10049K->10042K(1058816K)], 0.0231525 secs] [Times: user=0.16 sys=0.00, real=0.02 secs] 
java.lang.OutOfMemoryError: Metaspace
Dumping heap to java_pid5592.hprof ...
Heap dump file created [4525675 bytes in 0.014 secs]
[GC (Metadata GC Threshold) [PSYoungGen: 122K->96K(8192K)] 2333K->2306K(18432K), 0.0005350 secs] [Times: user=0.00 sys=0.00, real=0.00 secs] 
[Full GC (Metadata GC Threshold) [PSYoungGen: 96K->0K(8192K)] [ParOldGen: 2210K->2210K(10240K)] 2306K->2210K(18432K), [Metaspace: 10043K->10043K(1058816K)], 0.0095820 secs] [Times: user=0.02 sys=0.00, real=0.01 secs] 
[GC (Last ditch collection) [PSYoungGen: 0K->0K(8192K)] 2210K->2210K(18432K), 0.0003715 secs] [Times: user=0.00 sys=0.00, real=0.00 secs] 
[Full GC (Last ditch collection) [PSYoungGen: 0K->0K(8192K)] [ParOldGen: 2210K->2210K(10240K)] 2210K->2210K(18432K), [Metaspace: 10043K->10043K(1058816K)], 0.0043271 secs] [Times: user=0.00 sys=0.00, real=0.00 secs] 
****count=208
Heap
 PSYoungGen      total 8192K, used 246K [0x00000000ff600000, 0x0000000100000000, 0x0000000100000000)
  eden space 6144K, 4% used [0x00000000ff600000,0x00000000ff63d878,0x00000000ffc00000)
  from space 2048K, 0% used [0x00000000ffc00000,0x00000000ffc00000,0x00000000ffe00000)
  to   space 2048K, 0% used [0x00000000ffe00000,0x00000000ffe00000,0x0000000100000000)
 ParOldGen       total 10240K, used 2210K [0x00000000fec00000, 0x00000000ff600000, 0x00000000ff600000)
  object space 10240K, 21% used [0x00000000fec00000,0x00000000fee28ad8,0x00000000ff600000)
 Metaspace       used 10074K, capacity 10174K, committed 10240K, reserved 1058816K
  class space    used 787K, capacity 851K, committed 896K, reserved 1048576K
java.lang.OutOfMemoryError: Metaspace
    at org.springframework.cglib.core.ReflectUtils.defineClass(ReflectUtils.java:557)
    at org.springframework.cglib.core.AbstractClassGenerator.generate(AbstractClassGenerator.java:363)
    at org.springframework.cglib.proxy.Enhancer.generate(Enhancer.java:585)
    at org.springframework.cglib.core.AbstractClassGenerator$ClassLoaderData.get(AbstractClassGenerator.java:131)
    at org.springframework.cglib.core.AbstractClassGenerator.create(AbstractClassGenerator.java:319)
    at org.springframework.cglib.proxy.Enhancer.createHelper(Enhancer.java:572)
    at org.springframework.cglib.proxy.Enhancer.create(Enhancer.java:387)
    at com.jzj.jvmtest.oomtest.MethodAreaOOM.main(MethodAreaOOM.java:28)

Process finished with exit code 0

5.本機(jī)直接內(nèi)存溢出

5.1 設(shè)置JVM參數(shù)

-verbose:gc -Xms20M -Xmx20M  -Xmn10M -XX:+PrintGC -XX:+PrintGCDetails -XX:+HeapDumpOnOutOfMemoryError -XX:SurvivorRatio=8 -XX:MaxDirectMemorySize=5M

這里新加了參數(shù)-XX:MaxDirectMemorySize=5M 來(lái)控制本地直接內(nèi)存的大小

  • -XX:MaxDirectMemorySize=10M:設(shè)置本地直接內(nèi)存大小

5.2 測(cè)試代碼

package com.jzj.jvmtest.oomtest;
import sun.misc.VM;
import java.nio.ByteBuffer;
/**
 * 本地直接內(nèi)存溢出
 * 參數(shù)-XX:MaxDirectMemorySize=10M 來(lái)控制本地直接內(nèi)存的大小
 */
public class LocalDirectOOM extends ClassLoader {
    private static final int ONE_MB = 1024 * 1024;
    public static void main(String[] args) throws Exception {
        System.out.print("最大內(nèi)存: ");
        System.out.println(Runtime.getRuntime().maxMemory() / 1024 / 1024 + "MB");
        System.out.print("可用內(nèi)存: ");
        System.out.println(Runtime.getRuntime().freeMemory() / 1024 / 1024 + "MB");
        System.out.print("已使用內(nèi)存: ");
        System.out.println(Runtime.getRuntime().totalMemory() / 1024 / 1024 + "MB");
        //加了參數(shù) -XX:MaxDirectMemorySize=5M 后 ,打印出來(lái)就是 5M , 默認(rèn)的就是 最大內(nèi)存大小19M
        System.out.println("maxDirectMemorym設(shè)置大小" + VM.maxDirectMemory() / 1024 / 1024 + "MB");
        //分配最大本地內(nèi)存是1000000MB
        ByteBuffer byteBuffer = ByteBuffer.allocateDirect(1000000 * 1024 * 1024);
    }
}

5.3 運(yùn)行OOM日志

可以看到 日志java.lang.OutOfMemoryError: Direct buffer memory . 就是本地直接內(nèi)存 OOM溢出

最大內(nèi)存: 19MB
可用內(nèi)存: 16MB
已使用內(nèi)存: 19MB

maxDirectMemorym設(shè)置大小5MB
[GC (System.gc()) [PSYoungGen: 2683K->992K(9216K)] 2683K->1108K(19456K), 0.0007256 secs] [Times: user=0.16 sys=0.00, real=0.00 secs] 
[Full GC (System.gc()) [PSYoungGen: 992K->0K(9216K)] [ParOldGen: 116K->822K(10240K)] 1108K->822K(19456K), [Metaspace: 3440K->3440K(1056768K)], 0.0039306 secs] [Times: user=0.00 sys=0.00, real=0.00 secs] 
Exception in thread "main" java.lang.OutOfMemoryError: Direct buffer memory
    at java.nio.Bits.reserveMemory(Bits.java:694)
    at java.nio.DirectByteBuffer.<init>(DirectByteBuffer.java:123)
    at java.nio.ByteBuffer.allocateDirect(ByteBuffer.java:311)
    at com.jzj.jvmtest.oomtest.LocalDirectOOM.main(LocalDirectOOM.java:28)
Heap
 PSYoungGen      total 9216K, used 573K [0x00000000ff600000, 0x0000000100000000, 0x0000000100000000)  eden space 8192K, 7% used [0x00000000ff600000,0x00000000ff68f778,0x00000000ffe00000)  from space 1024K, 0% used [0x00000000ffe00000,0x00000000ffe00000,0x00000000fff00000)  to   space 1024K, 0% used [0x00000000fff00000,0x00000000fff00000,0x0000000100000000) ParOldGen       total 10240K, used 822K [0x00000000fec00000, 0x00000000ff600000, 0x00000000ff600000)  object space 10240K, 8% used [0x00000000fec00000,0x00000000feccd9f8,0x00000000ff600000) Metaspace       used 3520K, capacity 4500K, committed 4864K, reserved 1056768K  class space    used 386K, capacity 388K, committed 512K, reserved 1048576KProcess finished with exit code 1

綜上所述 ,我們來(lái)總結(jié)一下

  • 堆溢出, 堆中存放對(duì)象,線程共享 ------------ 瘋狂創(chuàng)建對(duì)象就可以導(dǎo)致堆溢出 Java heap space OOM
  • java虛擬機(jī)棧溢出,本地方法棧溢出 ,棧存放線程私有,refer指針, 局部變量表存放 對(duì)象8大數(shù)據(jù)類型,方法出口信息, 對(duì)象引用refer指針 ------------ 可以遞歸創(chuàng)建對(duì)象,如果棧深度大于虛擬機(jī)允許最大深度,或者再次創(chuàng)建對(duì)象是不允許擴(kuò)展棧 就會(huì) StackOverFlow 或者 OOM
  • 方法區(qū)溢出,方法區(qū)存放 類、靜態(tài)變量,常量,線程共享,稱為非堆, jdk1.7以前永久區(qū),jdk1.8以后元空間 ------------ 瘋狂創(chuàng)建常量Str信息或者cglib 創(chuàng)建類 Class信息,就會(huì)導(dǎo)致 Perm Space OOM 或者 Meta Space OOM
  • 本地直接內(nèi)存, 一般都是指定本地空間,沒(méi)指定就是最大內(nèi)存 ------------ ByteBuffer.allocateDirect 超出空間無(wú)法分配時(shí) 拋出 : Direct buffer memory OOM

以上就是JVM調(diào)優(yōu)OutOfMemoryError異常分析的詳細(xì)內(nèi)容,更多關(guān)于JVM調(diào)優(yōu)OutOfMemoryError異常的資料請(qǐng)關(guān)注腳本之家其它相關(guān)文章!

相關(guān)文章

  • Java Socket編程(二) Java面向連接的類

    Java Socket編程(二) Java面向連接的類

    Java Socket編程(二) Java面向連接的類...
    2006-12-12
  • Java中的Graphics2D類基本使用教程

    Java中的Graphics2D類基本使用教程

    這篇文章主要介紹了Java中的Graphics2D類基本使用教程,Graphics2D類較之Graphics類中的功能更加專業(yè),需要的朋友可以參考下
    2015-10-10
  • MyBatis如何通過(guò)攔截修改SQL

    MyBatis如何通過(guò)攔截修改SQL

    這篇文章主要介紹了MyBatis如何通過(guò)攔截修改SQL問(wèn)題,具有很好的參考價(jià)值,希望對(duì)大家有所幫助。如有錯(cuò)誤或未考慮完全的地方,望不吝賜教
    2022-11-11
  • JavaGUI菜單欄與文本和密碼及文本域組件使用詳解

    JavaGUI菜單欄與文本和密碼及文本域組件使用詳解

    這篇文章主要介紹了JavaGUI菜單欄與文本和密碼及文本域組件使用,文中通過(guò)示例代碼介紹的非常詳細(xì),對(duì)大家的學(xué)習(xí)或者工作具有一定的參考學(xué)習(xí)價(jià)值,需要的朋友們下面隨著小編來(lái)一起學(xué)習(xí)吧
    2023-03-03
  • SpringMVC結(jié)合天氣api實(shí)現(xiàn)天氣查詢

    SpringMVC結(jié)合天氣api實(shí)現(xiàn)天氣查詢

    這篇文章主要為大家詳細(xì)介紹了SpringMVC結(jié)合天氣api實(shí)現(xiàn)天氣查詢,具有一定的參考價(jià)值,感興趣的小伙伴們可以參考一下
    2017-05-05
  • java?LeetCode刷題稍有難度的貪心構(gòu)造算法

    java?LeetCode刷題稍有難度的貪心構(gòu)造算法

    這篇文章主要為大家介紹了java?LeetCode刷題稍有難度的貪心構(gòu)造題解示例,有需要的朋友可以借鑒參考下,希望能夠有所幫助,祝大家多多進(jìn)步,早日升職加薪
    2023-02-02
  • Spring?populateBean屬性賦值和自動(dòng)注入

    Spring?populateBean屬性賦值和自動(dòng)注入

    這篇文章主要為大家介紹了Spring?populateBean屬性賦值和自動(dòng)注入示例詳解,有需要的朋友可以借鑒參考下,希望能夠有所幫助,祝大家多多進(jìn)步,早日升職加薪
    2023-03-03
  • Java中的反射機(jī)制基本運(yùn)用詳解

    Java中的反射機(jī)制基本運(yùn)用詳解

    這篇文章主要介紹了Java 反射機(jī)制原理與用法,結(jié)合實(shí)例形式詳細(xì)分析了Java反射機(jī)制的相關(guān)概念、原理、基本使用方法及操作注意事項(xiàng),需要的朋友可以參考下
    2021-08-08
  • Java8中接口的新特性測(cè)試

    Java8中接口的新特性測(cè)試

    今天小編就為大家分享一篇關(guān)于Java8中接口的新特性測(cè)試,小編覺(jué)得內(nèi)容挺不錯(cuò)的,現(xiàn)在分享給大家,具有很好的參考價(jià)值,需要的朋友一起跟隨小編來(lái)看看吧
    2018-12-12
  • Java實(shí)現(xiàn)二叉搜索樹(shù)的插入、刪除功能

    Java實(shí)現(xiàn)二叉搜索樹(shù)的插入、刪除功能

    這篇文章主要介紹了Java實(shí)現(xiàn)二叉搜索樹(shù)的插入、刪除,本文通過(guò)實(shí)例代碼給大家介紹的非常詳細(xì),對(duì)大家的學(xué)習(xí)或工作具有一定的參考借鑒價(jià)值,需要的朋友可以參考下
    2022-01-01

最新評(píng)論