• jvm gc日志拿取与分析思路


    前言

        参考文章:Java中9种常见的CMS GC问题分析与解决 - 美团技术团队

    排查过程

    进入容器里

     生产应用是跑在docker上的,所以需要先进入到应用里面去,步骤如下

    1. docker ps 找到对应的应用id,比如  zxc

    2. 进入容器内部

    docker exec -it 7690ea7660bf sh

    docker exec -it 7690ea7660bf /bin/bash  有些是这个

    3. 查具体的应用   jps  如 1      注:jps -v 可以查看到配置的参数信息

    4. 查看gc 情况   jstat -gc 1 1000 10000   # 每1秒打印一次,连续打印10000次

    配置gc参数-1

    配置如下, 参数是固定的

    - JAVA_OPTS 中添加的信息

    -XX:+PrintGCDetails -XX:+PrintGCDateStamps  代表gc打印的详情格式

    -Xloggc:/opt/admin-gc.log  gc日志的位置,不配置默认会放到控制台

    1. blade-test:
    2. image: "${REGISTER}/test:${TAG}"
    3. environment:
    4. - TZ=Asia/Shanghai
    5. - JAVA_OPTS=-XX:+PrintGCDetails -XX:+PrintGCDateStamps -Xloggc:/opt/admin-gc.log
    6. privileged: true
    7. restart: always
    8. networks:
    9. - test_net

    如果上面的配置无效可以试试下面的

    配置gc参数-2

    查看你的项目是不是有Dockerfile文件,内容大概如下

    1. FROM openjdk:8-alpine
    2. MAINTAINER jiangshaonneg
    3. ADD ./lib/local_policy.jar /usr/lib/jvm/java-1.8-openjdk/jre/lib/security/local_policy.jar
    4. VOLUME /logs
    5. EXPOSE 8803/tcp
    6. RUN echo "java -jar web.jar -Dfile.encoding=UTF-8" > start.sh \
    7. && chmod 777 start.sh
    8. CMD ./start.sh

    如果有的话则直接把参数放到里面去即可,也就是直接放进去即可

    java -jar -XX:+PrintGCDetails -XX:+PrintGCDateStamps -Xloggc:/opt/game-app-gc.log web.jar

    docker部分操作

    docker cp /file mycontainer:/zxc     把文件放入docker内 mycontainer为容器id

    docker cp mycontainer:/zxc  /file    拿docker文件数据到主机,反过来即可

    如果是采用docker方式的就需要停止后重启容器才生效

    docker-compose down   停止相应的数据

    docker-compose up -d   启动,并且在后台

    arthas工具

    首页  https://arthas.aliyun.com/doc/

    基本命令,具体看文档

    dashboard  面板

    jvm 内存    --- 可以看到配置的参数生效没, 放在最上面了,在INPUT-ARGUMENTS中

    thread 线程

    ## jvm 参数查看是否生效

    剩下的就是拿日志了,怎么拿就是自己指定的,这里就不细说了

    分析日志

    分析网址

    我采用的是gceasy    https://gceasy.io/   可以大概知道哪些存在哪些问题,基本都是图形化的,下面说下几个相对重要的查看指标

    关键性能指标

    吞吐量是越高越好,这里基本接近了100,所以不会有太多问题了

    延迟是越短越好,这里稍微偏高,可能需要了解下啥原因

    GC 数据

    可以结合业务分析是否不合理

    GC原因(重要)

    这里可以很明显的看到大部分gc都是分配失败,很有可能就是因为内存分配不合理导致的,至于每种错误是什么,可以参考源码的返回,如下

    1. const char* GCCause::to_string(GCCause::Cause cause) {
    2. switch (cause) {
    3. case _java_lang_system_gc:
    4. return "System.gc()";
    5. case _full_gc_alot:
    6. return "FullGCAlot";
    7. case _scavenge_alot:
    8. return "ScavengeAlot";
    9. case _allocation_profiler:
    10. return "Allocation Profiler";
    11. case _jvmti_force_gc:
    12. return "JvmtiEnv ForceGarbageCollection";
    13. case _gc_locker:
    14. return "GCLocker Initiated GC";
    15. case _heap_inspection:
    16. return "Heap Inspection Initiated GC";
    17. case _heap_dump:
    18. return "Heap Dump Initiated GC";
    19. case _wb_young_gc:
    20. return "WhiteBox Initiated Young GC";
    21. case _wb_conc_mark:
    22. return "WhiteBox Initiated Concurrent Mark";
    23. case _wb_full_gc:
    24. return "WhiteBox Initiated Full GC";
    25. case _no_gc:
    26. return "No GC";
    27. case _allocation_failure:
    28. return "Allocation Failure";
    29. case _tenured_generation_full:
    30. return "Tenured Generation Full";
    31. case _metadata_GC_threshold:
    32. return "Metadata GC Threshold";
    33. case _metadata_GC_clear_soft_refs:
    34. return "Metadata GC Clear Soft References";
    35. case _cms_generation_full:
    36. return "CMS Generation Full";
    37. case _cms_initial_mark:
    38. return "CMS Initial Mark";
    39. case _cms_final_remark:
    40. return "CMS Final Remark";
    41. case _cms_concurrent_mark:
    42. return "CMS Concurrent Mark";
    43. case _old_generation_expanded_on_last_scavenge:
    44. return "Old Generation Expanded On Last Scavenge";
    45. case _old_generation_too_full_to_scavenge:
    46. return "Old Generation Too Full To Scavenge";
    47. case _adaptive_size_policy:
    48. return "Ergonomics";
    49. case _g1_inc_collection_pause:
    50. return "G1 Evacuation Pause";
    51. case _g1_humongous_allocation:
    52. return "G1 Humongous Allocation";
    53. case _dcmd_gc_run:
    54. return "Diagnostic Command";
    55. case _last_gc_cause:
    56. return "ILLEGAL VALUE - last gc cause - ILLEGAL VALUE";
    57. default:
    58. return "unknown GCCause";
    59. }
    60. ShouldNotReachHere();
    61. }

    最后一个就是网站的好处了,他会建议你一些优化点,在最上面建议里

    建议(重要,修改建议)

    可以看到几个明显的问题

    没有开启指针压缩

    没有初始化元空间大小分配

    结语

            到此gc日志的基本分析就结束了, 可以参考上面美团的文章进行了更全面的分析建议,这里只是初步的一些分析流程

  • 相关阅读:
    Java笔试题
    中秋遇到mysql死锁怎么办
    Java释疑
    【Mysql】Mysql内置函数介绍
    深度学习-第一章-Window下用Anaconda安装Yolov5
    录屏软件介绍
    差分+差分矩阵(更适合新手宝宝体质)
    KVM虚拟化介绍和安装使用方法
    第四章:指令系统
    快速搭建SSM框架
  • 原文地址:https://blog.csdn.net/zxc_user/article/details/136159666