`
youlong699
  • 浏览: 22576 次
  • 性别: Icon_minigender_1
  • 来自: 杭州
社区版块
存档分类
最新评论

一个cmsgc 频繁问题的排查

 
阅读更多

现象:一个平时运行2小时的任务,突然一天还没跑完,看系统cpu、load都不算高,接口监控发现rt从平时几ms到几十ms增加到了几千ms。

 

起初怀疑线程被阻塞了,然后top -p -H查看线程,返现有一个运行时间远远大于其他线程,jstack 查找发现是cmsgc 线程。 于是jstat -gcutil ,吓了一跳 eden、old全都是100%, fullgc 几千次了。。。。

 

于是考虑jmap -dump:file=dump  pid , 打算查找未释放的对象,但是应用内存4g多,不是我的小本能分析的了得。。 上火。

 

于是考虑重启应用,在内存占用还不是太高时dump出来进行分析。 在内存占用大约1.5g的时候,dump了一次,拖到本机(压缩一下,压缩率达到80%,网速不好时可以节省很多时间),mat分析一通,发现一个应用对象量格外大,那基本上跑不掉了。。

 

上btrace 跟踪在哪里产生的对象:

package com.sun.btrace.samples;

import static com.sun.btrace.BTraceUtils.exit;
import static com.sun.btrace.BTraceUtils.jstack;
import static com.sun.btrace.BTraceUtils.println;

import com.sun.btrace.annotations.BTrace;
import com.sun.btrace.annotations.OnMethod;

@BTrace
public class MethodStackTrace {
        private static int printCount = 0;
        @OnMethod(clazz = "com.xxx.common.lang.diagnostic.Profiler", method = "/start/")
        public static void func() {
            if(printCount++ < 20){
                        println("=======stack======");
                        jstack();
                        println("########end#########");
                }
            else 
                exit(0);
        }
}

 一下就抓住了。。具体的就是业务代码的使用逻辑问题了。

 

另外, 当dump文件太大不好分析时,只是为了查看对象情况,可以直接使用 sudo -u admin jmap -histo:live `pgrep java`  , 就能够按照内存占用量进行输出:

 num     #instances         #bytes  class name
----------------------------------------------
   1:        263195       28174696  [C
   2:        246862       25246080  [B
   3:        144815       22059552  <constMethodKlass>

 

还有个加强版的工具TBMap,可以按内存分区输出对象占用量:

Object Histogram:

#num    #all instances/bytes    #eden instances/bytes   #survivor instances/bytes       #old instances/bytes    #perm instances/bytes   #Class description
-----------------------------------------------------------------------------------
1:      1459670/664283552       765458/85719080 75663/99027992  582912/476992632        35637/2543848   char[]
2:      325529/44662232 303670/27425504 13/136664       3773/14967256   18073/2132808   byte[]
3:      1301337/41642784        537975/17215200 75898/2428736   651827/20858464 35637/1140384   java.lang.String
4:      101777/39235776 80265/4929544   8/28572496      7283/4950376    14221/783360    int[]
5:      601661/24910032 204358/6248200  63154/3887328   334149/14774504 0/0     java.lang.Object[]
6:      141225/21381376 0/0     0/0     0/0     141225/21381376 * ConstMethodKlass

 

 

分享到:
评论

相关推荐

    一次诡异的full gc查找问题全过程

    在本篇文章中,我们将分享一个 Full GC 问题排查过程,通过示例代码和实际操作,介绍了如何快速定位 Full GC 问题的原因和解决方案。 问题描述 在我们的服务中,突然出现了频繁的 Full GC 问题,而服务本身没有...

    【案例】记一次线上内存报警排查过程1

    在这个案例中,主要涉及的是线上服务的内存管理与问题排查,特别是针对Java应用程序的内存报警。以下是相关的知识点: 1. **内存报警**:当服务器的内存使用率超过一定阈值时,系统会发送报警,提示可能存在内存...

    jvisualvm visualgc

    VisualGC作为JVisualVM的一个重要插件,使得开发者能够直观地查看和分析Java应用程序的垃圾收集情况。本文将详细介绍这两款工具的使用和其背后的原理。 一、JVisualVM简介 JVisualVM是Oracle JDK的一部分,它允许...

    java 虚拟机问题分析大全

    性能问题是JVM另一大常见问题,包括但不限于CPU占用率过高、GC频繁、响应时间长等问题。 - **性能监控**:使用JVisualVM、JConsole等工具对JVM进行实时监控,收集CPU、内存、线程等方面的数据。 - **GC日志分析**:...

    lendengine应用JVM调优方案 - 面试用1

    总结来说,lendengine应用的JVM调优是一个综合性的工程,涉及到日志处理、内存管理、垃圾回收策略、线程池优化等多个方面。通过深入理解JVM的工作原理,针对性地调整相关参数,可以有效解决性能问题,提升服务的稳定...

    Java八股文之JVM与多线程

    3. **解决线上GC频繁问题**: 当遇到频繁的垃圾回收时,应首先通过监控工具分析GC日志,查看是否存在不合理的参数配置,如堆大小设置、新生代和老年代的垃圾收集器选择等。同时,检查是否有内存泄漏或异常的大对象...

    2023最新JVM+多线程面试真题

    3. **解决线上GC频繁问题**:这通常涉及到监控、参数调整和问题排查。可以使用JConsole、VisualVM等工具查看GC日志,分析FGC(Full GC)频率。检查JVM参数设置,如堆大小、新生代与老年代的比例、垃圾收集器类型等。...

    Jvm优化的Java -Demo

    "Jvm优化的Java - Demo"是一个项目,旨在演示如何调整JVM参数来优化Java应用程序的性能。通过这个项目,我们可以学习到JVM调优的一些核心概念和实践技巧。 首先,JVM参数调整是提高应用程序性能的重要手段。这通常...

    Java编程那些事儿_java_

    - 对象分配:减少短生命周期对象在老年代的分配,避免Full GC频繁触发。 - 泛型使用:避免过度使用泛型,因为泛型信息在编译后会被擦除,可能导致额外的类型检查和装箱操作。 - 数据结构优化:根据实际需求选择...

    练习JVM调优-jvm_demo.zip

    "练习JVM调优-jvm_demo.zip"是一个压缩包,包含了用于JVM调优实践的示例项目"jvm_demo-master"。通过这个项目,我们可以深入学习和理解JVM的工作原理和调优技术。 1. **JVM结构与工作原理**: - 类加载器:加载、...

    JVM常用指令手册JVM常用指令手册JVM常用指令手册

    最后,JVM的性能监控和调优是一个持续的过程,涉及到许多方面,如内存配置、线程管理、GC策略选择等。开发者应根据具体的应用场景和性能需求,灵活运用各种JVM指令进行调优。 总的来说,掌握JVM的常用指令和工作...

    理解JAVA虚拟机-内存管理、垃圾收集器.pptx

    在实际应用中,频繁的Full GC、不合理的内存设置以及内存泄露都是可能导致性能问题的因素,需要通过上述工具进行监控和分析,以便进行有效的内存管理和优化。对于内存排查,可以使用-jmap生成heap dump,然后用MAT...

    OutOfMemoryError.docx

    3. **大对象问题**:FrameworkLogEntry对象异常庞大,可能是由于日志记录过于频繁,每个日志条目都创建了一个大对象,超过了JVM对大对象的处理能力。 4. **JVM配置不当**:JVM的堆内存设置不合理,例如最大堆内存...

    JVM 20道面试题和答案.docx

    - **永久代(Perm Gen space)**:JDK 8之前的版本,存储类元数据,后被元空间替代,原因是防止Full GC频繁触发。 5. **垃圾收集算法**: - **标记-清除(Mark-Sweep)**:标记无用对象并清理,效率低,有碎片...

    1谈谈对java平台的理解1

    JVM作为一个抽象层,使得Java程序可以在任何支持JVM的操作系统上运行,无需重新编译。 Java语言的核心特性包括面向对象、自动内存管理(垃圾收集)、强类型、丰富的类库以及简洁的语法。其中,垃圾收集是Java的一大...

    jvm调优-jvm.zip

    6. **线程栈**:每个线程都有一个独立的栈,用于存储方法调用帧。`-Xss`参数可设置每个线程的栈大小,过大可能导致内存浪费,过小则可能引发StackOverflowError。 7. **编译优化**:JVM有即时编译器(JIT),会将...

    虚拟机垃圾回收调整策略.docx

    - **分代**:进一步细分,年轻代又分为Eden区和两个Survivor区,新创建的对象首先放在Eden区,经过一次Minor GC后存活的对象会移到Survivor区,多次存活后进入老年代。 - **性能考虑**:不同的垃圾收集器有不同的...

    聚焦java性能优化 打造亿级流量秒杀系统

    通过对以上各方面的深入理解和优化,我们可以有效地打造一个高性能、高可用的亿级流量秒杀系统,满足大规模并发场景下的业务需求。在实际操作中,需要根据具体业务特点和资源限制灵活调整优化策略。

    JVM调优总结.rar

    1. 根据应用特性调整内存分配,避免频繁GC。 2. 优化对象生命周期,减少短生命周期对象进入老年代。 3. 使用适当的垃圾收集器,平衡吞吐量和停顿时间。 4. 定期进行性能测试,监控系统指标,及时发现问题。 通过...

    JVM深入解析(JVM specification 和Sun的JVM的内存机制)

    - Java虚拟机栈:每个线程都有一个独立的栈,用于存储方法调用的状态,包括局部变量、操作数栈和方法返回地址。 - 本地方法栈:服务于Java的本地方法接口,为非Java语言(如C++)编写的native方法服务。 - 堆:...

Global site tag (gtag.js) - Google Analytics