• JVM 发生OOM的四种情况


    1、Java堆溢出:heap

    Java堆内存主要用来存放运行过程中所以的对象,该区域OOM异常一般会有如下错误信息;
    java.lang.OutofMemoryError:Java heap space
    此类错误一般通过Eclipse Memory Analyzer分析OOM时dump的内存快照就能分析出来,到底是由于程序原因导致的内存泄露,还是由于没有估计好JVM内存的大小而导致的内存溢出。

    另外,Java堆常用的JVM参数:
    -Xms:初始堆大小,默认值为物理内存的1/64(<1GB),默认(MinHeapFreeRatio参数可以调整)空余堆内存小于40%时,JVM就会增大堆直到-Xmx的最大限制.
    -Xmx:最大堆大小,默认值为物理内存的1/4(<1GB),默认(MaxHeapFreeRatio参数可以调整)空余堆内存大于70%时,JVM会减少堆直到 -Xms的最小限制
    -Xmn:年轻代大小(1.4or lator),此处的大小是(eden + 2 survivor space),与jmap -heap中显示的New gen是不同的。

    2、栈溢出:stack

    栈用来存储线程的局部变量表、操作数栈、动态链接、方法出口等信息。如果请求栈的深度不足时抛出的错误会包含类似下面的信息:
    java.lang.StackOverflowError

    另外,由于每个线程占的内存大概为1M,因此线程的创建也需要内存空间。操作系统可用内存-Xmx-MaxPermSize即是栈可用的内存,如果申请创建的线程比较多超过剩余内存的时候,也会抛出如下类似错误:

    java.lang.OutofMemoryError: unable to create new native thread

    相关的JVM参数有:
    -Xss: 每个线程的堆栈大小,JDK5.0以后每个线程堆栈大小为1M,以前每个线程堆栈大小为256K.
    在相同物理内存下,减小这个值能生成更多的线程.但是操作系统对一个进程内的线程数还是有限制的,不能无限生成,经验值在3000~5000左右。

    3、运行时常量溢出   constant
    运行时常量保存在方法区,存放的主要是编译器生成的各种字面量和符号引用,但是运行期间也可能将新的常量放入池中,比如String类的intern方法。
    如果该区域OOM,错误结果会包含类似下面的信息:

    java.lang.OutofMemoryError: PermGen space

    相关的JVM参数有:

    -XX:PermSize:设置持久代(perm gen)初始值,默认值为物理内存的1/64

    -XX:MaxPermSize:设置持久代最大值,默认为物理内存的1/4

    4、方法区溢出   directMemory
    方法区主要存储被虚拟机加载的类信息,如类名、访问修饰符、常量池、字段描述、方法描述等。理论上在JVM启动后该区域大小应该比较稳定,但是目前很多框架,比如Spring和Hibernate等在运行过程中都会动态生成类,因此也存在OOM的风险。
    如果该区域OOM,错误结果会包含类似下面的信息:

    java.lang.OutofMemoryError: PermGen space

    相关的JVM参数可以参考运行时常量。

    另外,在定位JVM内存问题的时候可以借助于一些辅助信息:

    1、日志相关
    -XX:+PrintGC:输出形式:
    [GC 118250K->113543K(130112K), 0.0094143 secs]
    [Full GC 121376K->10414K(130112K), 0.0650971 secs]
    -XX:+PrintGCDetails:输出形式:
    [GC [DefNew: 8614K->781K(9088K), 0.0123035 secs] 118250K->113543K(130112K), 0.0124633 secs]
    [GC [DefNew: 8614K->8614K(9088K), 0.0000665 secs][Tenured: 112761K->10414K(121024K), 0.0433488 secs] 121376K->10414K(130112K), 0.0436268 secs]
    -XX:+PrintGCTimeStamps:打印GC停顿耗时
    -XX:+PrintGCApplicationStoppedTime:打印垃圾回收期间程序暂停的时间.
    -XX:+PrintHeapAtGC:打印GC前后的详细堆栈信息

    -Xloggc:filename:把相关日志信息记录到文件以便分析.

    2、错误调试相关:
    -XX:ErrorFile=./hs_err_pid<pid>.log:如果JVM crashed,将错误日志输出到指定文件路径。
    -XX:HeapDumpPath=./java_pid<pid>.hprof:堆内存快照的存储文件路径。

    -XX:-HeapDumpOnOutOfMemoryError:在OOM时,输出一个dump.core文件,记录当时的堆内存快照

    3、类装载相关

    -XX:-TraceClassLoading:打印class装载信息到stdout。记Loaded状态。
    -XX:-TraceClassUnloading:打印class的卸载信息到stdout。记Unloaded状态。
  • 相关阅读:
    快速入门各种跨域
    常用知识点
    比较少用的格式
    git
    “没有用var声明的为全局变量”这种说法不准确
    类数组对象
    函数上下文的变量对象实例
    var a =10 与 a = 10的区别
    原型链与作用域链、执行上下文
    闭包的作用
  • 原文地址:https://www.cnblogs.com/baizhanshi/p/6704731.html
Copyright © 2020-2023  润新知