精华内容
下载资源
问答
  • OOM排查

    万次阅读 2019-06-13 15:35:32
    OOM排查过程步骤 1、先查看应用进程号pid: ps -ef | grep 应用名 2、查看pid垃圾回收情况:jstat -gc pid 5000(时间间隔) 即会每5秒一次显示进程号为68842的java进成的GC情况,显示内容如下图: 结果说明...

    OOM排查过程步骤

    1、先查看应用进程号pid:     ps  -ef | grep  应用名

    2、查看pid垃圾回收情况:  jstat  -gc  pid  5000(时间间隔)

    即会每5秒一次显示进程号为68842的java进成的GC情况,显示内容如下图:

    结果说明:显示内容说明如下(部分结果是通过其他其他参数显示的,暂不说明):

    S0C:年轻代中第一个survivor(幸存区)的容量 (字节) 

    S1C:年轻代中第二个survivor(幸存区)的容量 (字节) 

    S0U:年轻代中第一个survivor(幸存区)目前已使用空间 (字节) 

    S1U:年轻代中第二个survivor(幸存区)目前已使用空间 (字节) 

    EC:年轻代中Eden(伊甸园)的容量 (字节) 

    EU:年轻代中Eden(伊甸园)目前已使用空间 (字节) 

    OC:Old代的容量 (字节) 

    OU:Old代目前已使用空间 (字节) 

    PC:Perm(持久代)的容量 (字节) 

    PU:Perm(持久代)目前已使用空间 (字节) 

    YGC:从应用程序启动到采样时年轻代中gc次数 

    YGCT:从应用程序启动到采样时年轻代中gc所用时间(s) 

    FGC:从应用程序启动到采样时old代(全gc)gc次数 

    FGCT:从应用程序启动到采样时old代(全gc)gc所用时间(s) 

    GCT:从应用程序启动到采样时gc用的总时间(s) 

    NGCMN:年轻代(young)中初始化(最小)的大小 (字节) 

    NGCMX:年轻代(young)的最大容量 (字节) 

    NGC:年轻代(young)中当前的容量 (字节) 

    OGCMN:old代中初始化(最小)的大小 (字节) 

    OGCMX:old代的最大容量 (字节) 

    OGC:old代当前新生成的容量 (字节) 

    PGCMN:perm代中初始化(最小)的大小 (字节) 

    PGCMX:perm代的最大容量 (字节)   

    PGC:perm代当前新生成的容量 (字节) 

    S0:年轻代中第一个survivor(幸存区)已使用的占当前容量百分比 

    S1:年轻代中第二个survivor(幸存区)已使用的占当前容量百分比 

    E:年轻代中Eden(伊甸园)已使用的占当前容量百分比 

    O:old代已使用的占当前容量百分比 

    P:perm代已使用的占当前容量百分比 

    S0CMX:年轻代中第一个survivor(幸存区)的最大容量 (字节) 

    S1CMX :年轻代中第二个survivor(幸存区)的最大容量 (字节) 

    ECMX:年轻代中Eden(伊甸园)的最大容量 (字节) 

    DSS:当前需要survivor(幸存区)的容量 (字节)(Eden区已满) 

    TT: 持有次数限制 

    MTT : 最大持有次数限制 

    3、开启OOM快照: 

    -XX:+HeapDumpOnOutOfMemoryError(开启堆快照)

    -XX:HeapDumpPath=C:/m.hprof(保存文件到哪个目录)

    4、dump 查看方法栈信息:

    jstack -l  pid  >  /home/test/jstack.txt

    5、dump 查看JVM内存分配以及使用情况

    jmap  -heap  pid  >  /home/test/jmapHeap.txt

    6、dump jvm二进制的内存详细使用情况 (效果同在Tomcat的catalina.sh中添加 set JAVA_OPTS=%JAVA_OPTS% -server -XX:+HeapDumpOnOutOfMemoryError -XX:HeapDumpPath=/home/test//oom.hprof  此文件需要借用内存分析工具如:Memory Analyzer (MAT)来分析)

    jmap -dump:format=b,file=/home/test/oom.hprof  pid

     

    OOM一般有以下两种情况:

    1、年老代堆空间被占满

    异常:java.lang.OutOfMemoryError:java  heap space

    说明:这是最典型的内存泄漏方式,简单说就是所有堆空间都被无法回收的垃圾对象占满,虚拟机再也无法分配新空间

    解决方案:这种方式解决起来比较简单,一般就是根据垃圾回收前后的情况对比,同时根据对象引用情况(常见的集合对象引用)分析,基本都可以找到泄漏点

    2、持久代被占满

    异常:java.lang.OutOfMemoryError:PermGen space

    说明:Perm 空间被占满,无法为新的 class 分配存储空间而引发的异常。这个异常以前是没有的,但是在 java 大量使用反射的今天这个异常就比较常见了。主要原因是大量动态反射生成的类不断被加载,最终导致 Perm 区被占满。更可怕的是,不同的 classLoader 即便使用相同的类,但是都会对其进行加载,相当于同一个东西,如果有 N 个classLoader 那么它将会被加载 N 次。因此,在某些情况下,这个问题基本视为无解,当然,存在大量 classLoader 和大量反射类的情况并不多

    解决方案:增加持久代内存 ,例如:-XX:MaxPermSize=16M

    展开全文
  • JVM OOM 排查

    2021-04-22 06:14:50
    1、jdk 自带基础工具2、MAT 分析dump3、VM 实时监控4 、遇到过OOM内存溢出有哪些1、Java堆溢出 (java.lang.OutofMemoryError:Javaheap space)2、PermGen space3、StackOverflowError(虚拟机在扩展栈时无法申请到足够...

    1、jdk 自带基础工具

    2、MAT 分析dump

    3、VM 实时监控

    4 、遇到过OOM

    内存溢出有哪些1、Java堆溢出 (java.lang.OutofMemoryError:Java heap space)

    2、PermGen space

    3、StackOverflowError(虚拟机在扩展栈时无法申请到足够的内存空间)

    4、直接崩溃

    内存溢出与泄漏内存溢出 out of memory:

    是指程序在申请内存时,没有足够的内存空间供其使用,出现out of memory;

    内存泄露 memory leak,

    是指程序在申请内存后,无法释放已申请的内存空间,一次内存泄露危害可以忽略,但内存泄露堆积后果很严重,无论多少内存,迟早会被占光

    一、jdk 自带基础工具

    1、 jps(Java Virtual Machine Process Status Tool)

    实际中这是最常用的命令,下面要介绍的小工具更多的都是先要使用jps查看出当前有哪些Java进程,获取该Java进程的id后再对该进程进行处理。jps  [options]  [hostid]

    -q 不输出类名、Jar名和传入main方法的参数

    -m 输出传入main方法的参数

    -l 输出main类或Jar的全限名

    -v 输出传入JVM的参数[root@iZbp11b3erzreb4xi5utvzZ /]# jps -ml

    22611 /usr/lib/jenkins/jenkins.war --logfile=/var/log/jenkins/jenkins.log --webroot=/var/cache/jenkins/war 740 org.apache.catalina.startup.Bootstrap start19942 org.apache.zookeeper.server.quorum.QuorumPeerMain /mnt/zk/zookeeper-3.4.13/bin/../conf/zoo.cfg20537 sun.tools.jps.Jps -ml11309 org.sonatype.nexus.bootstrap.jsw.JswLauncher ./conf/jetty.xml ./conf/jetty-requestlog.xml32190 org.apache.catalina.startup.Bootstrap start

    2、 jstack

    jstack 主要用来查看某个Java进程内的线程堆栈信息。语法格式如下:

    jstack  [option]  pid

    jstack [option]  executable core

    jstack   [option]   [server-id@]remote-hostname-or-ip

    pid: java应用程序的进程号,一般可以通过jps来获得;

    executable:产生core dump的java可执行程序($JAVA_HOME/bin/java);

    core:打印出的core文件;(jvm崩溃产生的core文件,从hs_err_pid log file 查看)

    emote-hostname-or-ip:远程debug服务器的名称或IP

    server-id: 唯一id,假如一台主机上多个远程debug服务;option 说明如下:

    -l,会打印出额外的锁信息,在发生死锁时可以用jstack -l pid来观察锁持有情况

    -m 不仅会输出Java堆栈信息,还会输出C/C++堆栈信息(比如Native方法)

    jstack -l  pid

    91e2b102dd4c?tdsourcetag=s_pcqq_aiomsg

    查看耗时线程

    top -Hp pid

    91e2b102dd4c?tdsourcetag=s_pcqq_aiomsgprintf "%x\n" 21226

    获取耗时线程id 的十六进制

    52ec

    获取耗时信息

    [root@2 logs]# jstack 21222 | grep 52ec

    "GC task thread#3 (ParallelGC)" os_prio=0 tid=0x00007fee24027000 nid=0x52ec runnable

    3、jmap(Memory Map)jmap导出堆内存,然后使用jhat来进行分析

    jmap [option] pid

    jmap [option] executable core

    jmap [option] [server-id@]remote-hostname-or-ip

    参数如下:-heap:打印jvm heap的情况

    -histo:打印jvm heap的直方图。其输出信息包括类名,对象数量,对象占用大小。

    -histo:live :同上,但是只打印存活对象的情况

    -permstat:打印permanent generation heap情况(持久代)

    输出 类加载器名称、对象是否存活、对象地址、父类加载器、已加载的类大小等信息

    -dump:    打印 dump(内存使用) 日志文件

    jmap -heap pid

    查看进程堆内存使用情况:包括使用的GC算法、堆配置参数和各代中堆内存使用:

    [root@iZbp11b3erzreb4xi5utvzZ ~]# jmap -heap 32326

    Attaching to process ID 32326, please wait...

    Debugger attached successfully.

    Server compiler detected.

    JVM version is 25.161-b12

    using thread-local object allocation.

    Parallel GC with 4 thread(s)

    Heap Configuration:

    MinHeapFreeRatio        = 0

    MaxHeapFreeRatio        = 100

    MaxHeapSize              = 536870912 (512.0MB)

    NewSize                  = 201326592 (192.0MB)

    MaxNewSize              = 201326592 (192.0MB)

    OldSize                  = 335544320 (320.0MB)

    NewRatio                = 2

    SurvivorRatio            = 8

    MetaspaceSize            = 21807104 (20.796875MB)

    CompressedClassSpaceSize = 1073741824 (1024.0MB)

    MaxMetaspaceSize        = 17592186044415 MB

    G1HeapRegionSize        = 0 (0.0MB)

    Heap Usage:

    PS Young Generation

    Eden Space:

    capacity = 121634816 (116.0MB)

    used    = 105409240 (100.52608489990234MB)

    free    = 16225576 (15.473915100097656MB)

    86.6604180171572% used

    From Space:

    capacity = 38797312 (37.0MB)

    used    = 6225208 (5.936820983886719MB)

    free    = 32572104 (31.06317901611328MB)

    16.045462118612754% used

    To Space:

    capacity = 39845888 (38.0MB)

    used    = 0 (0.0MB)

    free    = 39845888 (38.0MB)

    0.0% used

    PS Old Generation

    capacity = 335544320 (320.0MB)

    used    = 19401584 (18.502792358398438MB)

    free    = 316142736 (301.49720764160156MB)

    5.782122611999512% used

    19968 interned Strings occupying 2526840 bytes.

    jmap -histo[:live] pid

    查看堆内存中的对象数目、大小统计直方图,如果带上live则只统计活对象

    [root@iZbp11b3erzreb4xi5utvzZ ~]# jmap -histo 32326

    num    #instances        #bytes  class name

    ----------------------------------------------

    1:        351157      49044840  [C

    2:        140145      26768472  [B

    3:        30637      18927560  [I

    4:        191987        4607688  java.lang.String

    5:        46693        3523560  [Ljava.lang.Object;

    6:        27813        2447544  java.lang.reflect.Method

    7:        30591        2447048  [S

    8:        58522        2340880  java.util.TreeMap$Entry

    9:        81040        1683096  [Ljava.lang.Class;

    10:        38542        1541680  java.util.HashMap$KeyIterator

    11:        44546        1069104  java.lang.StringBuilder

    12:        18696        1046976  java.util.concurrent.ConcurrentHashMap$KeyIterator

    13:        37638        903312  java.util.Collections$UnmodifiableCollection$1

    14:        10197        896216  [Ljava.util.HashMap$Node;

    15:          7902        879416  java.lang.Class

    class name是对象类型,说明如下:B byte

    C char

    D double

    F float

    I int

    J long

    Z boolean

    [ 数组,如[I表示int[]

    [L+类名 其他对象

    jmap -dump:format=b,file=dumpFileName pid[root@iZbp11b3erzreb4xi5utvzZ ~]# jmap -dump:format=b,file=/mnt/d.bat 32326

    Dumping heap to /mnt/d.bat ...

    Heap dump file created

    问题:

    这些工具真靠谱吗?

    大应用异常下 直接使用jmap jstack 根本无法加载内存信息或者耗时很久?

    有什么可以替代吗?

    gcore?

    二、MAT 分析Dump

    Dump 是什么Dump是反应Java堆使用情况的内存镜像,其中主要包括系统信息、虚拟机属性、完整的线程Dump、所有类和对象的状态等。 一般,在内存不足、GC异常等情况下,我们就会怀疑有内存泄漏。这个时候我们就可以制作堆Dump来查看具体情况。分析原因。

    Dump 文件的分析有多种方式1、命令jhat 分析(麻烦)

    2、VisualVM 工具分析

    3、MAT 分析

    MAT分析

    J2SE中提供了一个简单的命令行工具来对java程序的cpu和heap进行 profiling(剖析面),叫做HPROF

    Shallow Size

    对象自身占用的内存大小,不包括它引用的对象。

    针对非数组类型的对象,它的大小就是对象与它所有的成员变量大小的总和。当然这里面还会包括一些java语言特性的数据存储单元。

    针对数组类型的对象,它的大小是数组元素对象的大小总和。

    Retained Size

    Retained Size=当前对象大小+当前对象可直接或间接引用到的对象的大小总和。(间接引用的含义:A->B->C, C就是间接引用)

    换句话说,Retained Size就是当前对象被GC后,从Heap上总共能释放掉的内存。

    不过,释放的时候还要排除被GC Roots直接或间接引用的对象。他们暂时不会被被当做Garbage。

    List objects --> with outgoing references

    :查看当前对象持有的外部对象引用(在对象关系图中为从当前对象指向外的箭头)

    List objects --> with incoming references

    :查看当前对象被哪些外部对象所引用(在对象关系图中为指向当前对象的箭头)

    三、VM 实时监控

    四、遇到过OOM

    1、刚开始用eclipse 开发 ,没事就本地OOM

    2、DateForm oom

    3、POI 导出xls 包含图片

    4、万恶的死循环

    5、hashmap

    6、websocket 大内存长久占用

    事故:

    1、遇到fullgc 了,oom了?完蛋

    2、抓不出来dump ?完蛋

    3、jmap、jstack 都用不了?完蛋

    1、记录时间点

    2、抓住一切日志可用日志(应用日志)

    3、慢慢分析

    参考

    GC:https://www.cnblogs.com/wozixiaoyao/p/5658950.html

    jstack:https://www.jianshu.com/p/08b816d9b34f

    executable core:https://lydawen.iteye.com/blog/2215300

    内存划分:https://www.cnblogs.com/haitaofeiyang/p/8392268.html

    mat:http://www.cnblogs.com/trust-freedom/p/6744948.html#histogram

    oom:https://mp.weixin.qq.com/s/kJe8WScwB4XcqRNE2vM7EA?

    展开全文
  • 主要给大家介绍了一次OOM问题排查过程,文中通过示例代码介绍的非常详细,对大家的学习或者工作具有一定的参考学习价值,需要的朋友们下面来一起学习学习吧
  • OOM排查与定位

    千次阅读 2019-11-05 15:44:32
    某Java服务(假设PID=19813)出现了OOM,最常见的原因为: 有可能是内存分配确实过小,而正常业务使用了大量内存 某一个对象被频繁申请,却没有释放,内存不断泄漏,导致内存耗尽 某一个资源被频繁申请,系统资源...

    某Java服务(假设PID=19813)出现了OOM,最常见的原因为:
    有可能是内存分配确实过小,而正常业务使用了大量内存
    某一个对象被频繁申请,却没有释放,内存不断泄漏,导致内存耗尽
    某一个资源被频繁申请,系统资源耗尽,例如:不断创建线程,不断发起网络连接
    三种情况:

    1 “本身资源不够”

    2 “申请资源太多”

    3: “资源耗尽”。
     更具体的,可以使用以下工具逐一排查。

    jps列出所有java进程

    一、确认是不是内存本身就分配过小
    jmap -heap 19813


    如上图,可以查看新生代,老生代堆内存的分配大小以及使用情况,看是否本身分配过小。

    二、找到最耗内存的对象
    方法:jmap -histo:live 19813  |  more

    如上图,输入命令后,会以表格的形式显示存活对象的信息,并按照所占内存大小排序:
    实例数
    所占内存大小
    类名
    是不是很直观?对于实例数较多,占用内存大小较多的实例/类,相关的代码就要针对性review了。
    上图中占内存最多的对象是char 类型 ,共占用内存11M,属于正常使用范围。

     1:         79988       11142328  [C


    如果发现某类对象占用内存很大(例如几个G),很可能是类对象创建太多,且一直未释放。例如:
    申请完资源后,未调用close()或dispose()释放资源
    消费者消费速度慢(或停止消费了),而生产者不断往队列中投递任务,导致队列中任务累积过多
    画外音:线上执行该命令会强制执行一次fgc。另外还可以dump内存进行分析。


    三、确认是否是资源耗尽工具:
    pstree
    netstat
    查看进程创建的线程数,以及网络连接数,如果资源耗尽,也可能出现OOM。 这里介绍另一种方法,通过
    /proc/${PID}/fd
    /proc/${PID}/task
    可以分别查看句柄详情和线程数。 例如,某一台线上服务器的sshd进程PID是19813,查看
    ll /proc/19813/fd
    ll /proc/19813/task

     

    展开全文
  • 常见OOM排查和处理

    千次阅读 2020-11-05 16:47:01
    总结一些常见OOM 1.java.lang.OutOfMemoryError: Java heap space 首先在错误提示那已经提示了OOM发生在堆空间里面,因为在本地idea,所以为了模拟这种情况配置了VM Options :-Xms10m -Xmx10m -XX:+PrintGCDetails ...

     

    总结一些常见OOM

    主要有以下几个OOM报错

    目录

    1.java.lang.OutOfMemoryError: Java heap space

     堆OOM原因:

    排查和解决方案:

    排查:

    解决:

    2.java.lang.OutOfMemoryError: GC overhead limit exceeded

    3.java.lang.OutOfMemoryError:unable to create new native thread

    解决方法:

    4.OutOfMemoryError: Direct buffer memory 

    5.java.lang.OutOfMemoryError: Metaspace


    1.java.lang.OutOfMemoryError: Java heap space

    首先在错误提示那已经提示了OOM发生在堆空间里面,因为在本地idea,所以为了模拟这种情况配置了VM Options :-Xms10m -Xmx10m -XX:+PrintGCDetails

    为温故而知新,我还是解释一下各参数的含义 -Xms10m代表堆初始化大小为10m;-Xmx10m代表堆最大为10M; -XX:+PrintGCDetails代表打印日志,为什么加这个呢,因为我在本地运行,为了排查oom的前因后果,所以加这个命令查看jvm的垃圾回收情况。

    一个小知识点:jvm的参数大部分都是-XX:+/-{KEY}或者是-XX:key=value形式,为什么出现-Xms,-Xmx,-Xss的命令?

    其实-Xms等于-XX:InitialHeapSize;-Xmx 等同于-XX:MaxHeapSize;而-Xss等同于-XX:ThreadStackSize;

    因此其实-X命令等于-XX命令。

    另外多说一句,如果我们自己不设置的话 -Xms默认为系统内存的1/64,-Xmx默认为系统内存的1/4。

    public class OutOfMemoryGCLimitExceed {
    
        public static void addRandomDataToMap() {
            Map<Integer, String> dataMap = new HashMap<>();
            Random r = new Random();
            while (true) {
                dataMap.put(r.nextInt(), String.valueOf(r.nextInt()));
            }
        }
    
        public static void main(String[] args) throws InterruptedException {
            addRandomDataToMap();
    //        Thread.sleep(20000);
    
        }
    }

    于是乎,执行该程序时很快就报了堆的OOM。

    先来看看报错信息

     

     堆OOM原因:

    首先从打印的日志里面可以看到在jdk8里面,如果我们不配置垃圾回收器的话,默认选择的是parallel scavenger和parallel old 作为年轻代老年代的并行垃圾回收器。随着for循环不断new对象,可以看到先进行了一会分配对象失败(Allocation Failure)后,程序不停的进行了Full GC ,然后在报错的前夕,老年代已经接近10M,也就是因为对象的不停创建导致了老年代区不负重荷,最终导致了堆里面的OOM。

    另外:虽然在本例子里面没有出现,但是这个也是需要考虑的一点是,有没有可能是因为发生内存泄漏导致的堆的OOM。

    排查和解决方案:

    排查:

    1.在本地环境里面可以使用jmap和jvm参数方式-XX:+PrintGCDetails 查看内存和gc日志情况。

    2.jmap使用:

       2.1 先jps -l 查询java程序的进程 获得pid

       2.2 然后可以使用jmap -histo:live pid显示内存存活的实例数和类;也可以使用jmap -dump:format=b,file=heapDump.phrof pid 打印出dump日志

     然而这种方式需要特别注意

    1.使用jmap -histo:live pid时,会产生FullGC ,也就是说如果你在生产环境使用了这个命令,特别是对于一些大型公司而言,有可能因为FullGC而造成的问题就很大了,因此这个命令在生产环境的使用要慎之又慎

    2.使用jmap -dump:format=b,file=heapDump.phrof pid时会将实时内存信息导出,如果heap比较大,那么就会很耗时,很可能会导致应用的暂停,因此使用这个命令需要慎之又慎。

    因此我看到网上有另一种工具arthas(不过我没用过,需要你们自行了解)

    3.那么另一种方式就是jvm参数,比如-XX:+HeapDumpOnOutOfMerroryError和配合-XX:HeapDumpPath的使用,会在OOM异常时导出heapDump文件;

    或者使用-Xloggc:/opt/xxx/.../oom.log,-XX:+UseGCLogFileRotaion(如果日志记满了就循环写入到日志文件里),-XX:NumbersOfGCLogFiles=n,-XX:GCLogFileSize=20M,-XX:+PrintGCDetails,-XX:+PrintGCDateStamps,-XX:+PrintGCCause

    解决:

    1.简单粗暴,堆空间不够那就增加堆空间的大小,把-Xms和-Xmx扩大;

    2.需要观察稳定运行期,FullGC后会不会有内存增大现象,会不会有内存泄露的情况

    3.查看代码是否因为设计原因,导致很多垃圾对象产生。比如某些对象能不能不用每次都新建,而使用单例模式。对于长生命周期对象对象后续不用了,object=null可以辅助GC,一旦方法脱离了作用域,相应的局部变量应用就会被注销。

     

    2.java.lang.OutOfMemoryError: GC overhead limit exceeded

    代码跟第一个一样,但是我把jvm options改成了这样:-Xms300m -Xmx300m -XX:+PrintGCDetails

    public class OutOfMemoryGCLimitExceed {
    
        public static void addRandomDataToMap() {
            Map<Integer, String> dataMap = new HashMap<>();
            Random r = new Random();
            while (true) {
                dataMap.put(r.nextInt(), String.valueOf(r.nextInt()));
            }
        }
    
        public static void main(String[] args) throws InterruptedException {
            addRandomDataToMap();
    //        Thread.sleep(20000);
    
        }
    }

     报错截图:

    先来看看GC overhead limit exceeded发生的原因:

    Oracle的官方解释

    Exception in thread thread_name: java.lang.OutOfMemoryError: GC Overhead limit exceeded
    Cause: The detail message "GC overhead limit exceeded" indicates that the garbage collector is running all the time and Java program is making very slow progress. After a garbage collection, if the Java process is spending more than approximately 98% of its time doing garbage collection and if it is recovering less than 2% of the heap and has been doing so far the last 5 (compile time constant) consecutive garbage collections, then a java.lang.OutOfMemoryError is thrown. This exception is typically thrown because the amount of live data barely fits into the Java heap having little free space for new allocations.
    Action: Increase the heap size. The java.lang.OutOfMemoryError exception for GC Overhead limit exceeded can be turned off with the command line flag -XX:-UseGCOverheadLimit.

    大概的意思是说,java进程使用了超过98%的时间来回收垃圾,却只回收了2%的垃圾。同时,官方文档也说了你可以使用  -XX:-UseGCOverheadLimit把这个报错给关闭

    如果我们启用了这个jvm配置-XX:-UseGCOverheadLimit,再执行我们的程序,发现还是报了java.lang.OutOfMemoryError: Java heap space的错误,也就是说我们也可以用heap oom的解决方案去分析解决这个报错。

    因此,这个错误其实是通知我们gc线程在不断的FullGC然后却回收了不到2%的垃圾,这个时候,我们可以去dump文件查看哪些对象占大部分空间,然后根据业务去进行分析。

    3.java.lang.OutOfMemoryError:unable to create new native thread

    造成这个原因是因为线程数太多超过了限制,报了错。

    这个线程限制数的大小在不同的服务器可能有不同的设置,比如可以在linux环境下输入命令ulimit -u

    在我的阿里云上这个限制数是7271

    出现这个问题原因其实很有可能出现在高并发的情况下,由于一段时间内接口被不断调用,因而线程调用量或者每个接口内需要使用多线程处理数据导致线程数飙升,因此是否可以在某些重大活动面前增加节点,调配好适合的负载均衡策略也是解决这个问题的方法之一。

    解决方法:

    1.需要尽可能降低:需要分析应用是否真的需要创建这么多线程,如果不是,改代码将线程数降到最低。

    2.如果真的需要使用这么多的线程,那么就去设置服务器的最大线程数

    4.OutOfMemoryError: Direct buffer memory 

    这个异常其实我没有见过,因此,这个我是从网上学习总结。

    这个是我写的一个小demo,jvm options是-Xms10m -Xmx10m -XX:+PrintGCDetails -XX:MaxDirectMemorySize=5m。

    public class DirectBufferOOMTest {
        public static void main(String[] args) {
            //设置directMerrory小点
            ByteBuffer b = ByteBuffer.allocateDirect(6*1024*1024);
        }
    }

    因为-XX:MaxDirectMemorySize=5m,而我创建了一个6m的对象分配在直接内存那,很明显就会报错了,来看看报错截图

     通常在nio的情况下时,使用ByteBuffer写入缓存,写出缓存。

    而使用ByteBuffer.allocate(capacity),是把缓存写在jvm的内存里面,收到gc管理的,且需要内存拷贝因此速度较慢

    而使用ByteBuffer.allocateDirect(capacity)则是把缓存写在操作系统本地内存,因此不用gc的管理,不需要内存拷贝速度很快。

     

    5.java.lang.OutOfMemoryError: Metaspace

    遇到metaspace的oom,再次温故而知新一下,在jdk1.8后,移除了永久代,换成了metaspace(元空间),首先得先说一句,就是metaspace也是在堆外,因此gc是无法管理的。

    这次我在jvm options 加了oom时打印dump文件,接下来看看dump文件

    JVM OPTIONS:-XX:MetaspaceSize=8m -XX:MaxMetaspaceSize=10m -XX:+PrintGCDetails -XX:+HeapDumpOnOutOfMemoryError -XX:HeapDumpPath=C:\OwnCode\lamb\lambDump.phrof

     代码也是网上找的,模拟metaspace的错误

    public class OutOfMerroryMetaSpace {
        static class innerClass{
            private String sex;
        }
    
        static class OOMTest {
    
        }
    
        public static void main(String[] args) {
            int i = 0;
            try {
                while (true) {
                    i++;
                    Enhancer enhancer = new Enhancer();
                    enhancer.setSuperclass(OOMTest.class);
                    enhancer.setUseCache(false);
                    enhancer.setCallback(new MethodInterceptor() {
                        @Override
                        public Object intercept(Object o, Method method, Object[] objects, MethodProxy methodProxy) throws Throwable {
                            return methodProxy.invokeSuper(o, args);
                        }
                    });
                    enhancer.create();
                }
            } catch (Throwable e) {
                System.out.println("****i=" + i);
                e.printStackTrace();
            }
    
    
        }
    }

     接下来看看dump文件

    找到这个代理对象有1638个,总大小为80262。

    那么我们就来看看metaspace用来存什么数据:

    在方法区里面主要存放了类型的相关信息:如类名,访问修饰符,常量池,字段描述,方法描述等。

    而经过cglib直接操作字节码运行时,则会生成大量的动态类,这些类就需要各自保存他们的方法描述,字段描述,类名等,从而占据了metaspace的空间。

     解决方法:

    1.直接增加-XX:MaxMetaspaceSize的值

    2.出现metaspace的OOM问题,一个很可能是常量池增加的太大,一个是因为使用了动态代理技术,经过dump文件分析,动态类太多,应该从代码里面去分析,是否需要这么多动态代理。

    展开全文
  • OOM排查工具

    2020-08-23 23:34:24
    工作中碰到了很多次OOM,因此需要去排查相关的问题。 使用过一些工具进行排查。 JVM自带的:jps、jstack、jstat、jmap、jhat等,本地使用jconsole、jvisualVM 其他开源工具:MAT、greys、arthas、IBM Heap...
  • 工作中遇到了OOM问题需要排查,在此做一下分享,也做一下笔记 这里模拟了工作中的OOM场景,实际代码就不拿出来了,... * @description OOM排查与优化 */ public class OptimizeOOM { public static void main(...
  • 线上服务器oom排查总结

    千次阅读 2019-12-20 14:48:25
    1.oom情况 出现java.lang.OutOfMemoryError: GC overhead limit exceeded 一般是(某个循环里可能性最大)在不停的分配对象,但是分配的太多,把堆撑爆了。 出现java.lang.OutOfMemoryError: Java heap space一般...
  • java 导致OOM 排查历程

    2020-03-08 00:35:37
    java 一次OOM故障 分析 先看了下监控 发现内存在逐渐增加 ,然后cpu 有一个飙升的情况, 后 java 进程被杀, OOM确实会造成CPU飙升,系统卡顿,然后系统会选择杀死某些进程以释放空间就把java杀了 第一步 补救措施 恢复...
  • 一次线上OOM排查总结

    2019-09-28 22:05:05
    现象 公司新上线的一个数据入库...排查过程 因为只有这个项目上出现这种情况,初步认为是该项目上数据量较大,调整了tomcat内存大小 打开tomcat的bin目录下的catalins.sh文件 在cygwin=false之上 添加以下语...
  • 记一次 OOM 排查过程

    2020-05-17 19:53:16
    经过上面的分析,需要注意的是设置最大堆内存大小,因此设置 JVM 参数: -Xmx1024m 微观角度分析 扩大堆内存最大值可以解决 OOM 问题,但是我们并没有找到真正导致 OOM 问题的原因(当然在这个例子中的最大原因是 ...
  • 排查: 三、最终排查原因 四、解决方案考虑有四种 (1)在kettle中对并行执行的任务增加一个随机时间等待,如下 (2)30个并行任务分3次跑 (3)考虑引入zabbix和zaa监控框架 (4)将部分项目迁移到别的服务器...
  • OOM排查步骤

    2021-10-09 18:34:43
    1..hprof文档 通常在OOM时会记录内存情况供分析。启动时指定jvm参数 -XX:+HeapDumpOnOutOfMemoryError -XX:HeapDumpPath=D:\log\projects\donottouchme.hprof (可选) 就见过OOM没hprof文件也没监控的,怎么死的都不...
  • Xms1024m -Xmx1024m -XX:+UseG1GC -XX:+HeapDumpOnOutOfMemoryError -XX:HeapDumpPath=./ -jar Alpha_2.jar JVM可视化工具我用的JDK自带的 JConsole,方便了解内存占用情况 以服务器程序内存溢出排查为例 要注意的是...
  • OOM 排查 工具方法

    千次阅读 2017-05-04 09:49:03
    开始我们一度认为是Dump文件有错,后来上网搜索才知道,因为MAT的主要目标是排查内存占用量,所以默认大小是不计算不可达对象的——而我们的String都是不可达对象。对应Eclipse的文档里有介绍...
  • oom排查

    2021-03-14 23:59:53
    -XX:+HeapDumpOutOfMemoryError 在抛出OOM异常时会生成dump文件,使用IBM HeapAnalyzer分析具体情况
  • 在开发项目中发生了一次OOM问题,通过crash 平台查看上报信息,发现在很多的页面都有报这个错误,但是相同的出错都是以下的错误,看不到APP的堆栈只能看到是线程池创建有问题的堆栈信息,如下所示: java.lang....
  • 一次OOM排查过程

    2017-02-19 10:17:00
    前段时间系统经常出现OOM,服务很不稳定,偶尔会有java进程不存在的情况,临时解决方案只能是重启。 二、辅助工具 1.top 用top查看,发现内存占用(%MEM)挺多,其他指标均正常。 2.dmesg 如果发现自己的...
  • OOM排查思路

    2021-05-19 17:35:09
    什么是OOM 简单来说,就是程序的内存不够了,挂掉了 OOM的原因 oom的原因其实就一个,内存不够了,我们要细分的就是哪里的内存不够了,以及为什么内存不够了 栈溢出 这种情况属实比较少,一般就是栈调用太深了,比如...
  • OOM排查和处理

    2022-01-20 13:30:10
    1、OOM异常:java.lang.OutOfMemoryError: Java heap space Xms10m代表堆初始化大小为10m; Xmx10m代表堆最大为10M; XX:+PrintGCDetails代表打印日志 Xms等于-XX:InitialHeapSize;-Xmx 等同于-XX:MaxHeapSize;...
  • 循环内new实例会增加内存开销。 改为在循环外: 总结一下可能引发内存溢出的几点原因:  1.内存中加载的数据量过于庞大,如一次从数据库取出过多数据,需手动垃圾回收;  2.集合类中有对对象的... 3.... 4.... 5.......
  • 本文阐述分析了 Android 上面 OOM 出现的原因以及一些排查方法。并特别针对图片加载占用内存导致 OOM 的问题,提出了一些解决办法。
  • 一次应用OOM排查

    2018-04-30 00:27:46
    前段时间系统经常出现OOM,每次出现之后系统会出现各种问题,临时解决方案只能是重启,然后等找到问题后再发布解决。 线上问题日志如下:1Exception in thread "msgWorkTP-811568603-1-thread-6" java....
  • 记一次OOM排查过程(入门版)

    千次阅读 2019-06-06 10:43:14
    第一次线上遇到问题,最近也在学jvm,记录一下,算是一个入门版jvm故障排查,希望能给新手带来一点干货。 背景 机器 (2c8g) 默认jvm部分关键...HeapDumpOnOutOfMemoryError 这个是故障排查关键,会在OOM的时候生成...

空空如也

空空如也

1 2 3 4 5 ... 20
收藏数 13,944
精华内容 5,577
关键字:

oom排查

友情链接: ShootGame.rar