• JVM内存堆栈分析 lcl


    一、JVM线程堆栈数据分析

      JVM 内部线程主要分为以下几种:

        VM 线程:单例的 VMThread 对象,负责执行 VM 操作;

        定时任务线程:单例的 WatcherThread 对象, 模拟在 VM 中执行定时操作的计时器中断;

        GC 线程:垃圾收集器中,用于支持并行和并发垃圾回收的线程;

        编译器线程: 将字节码编译为本地机器代码;

        信号分发线程:等待进程指示的信号,并将其分配给Java 级别的信号处理方法。

      GC进行垃圾回收时,会STW,那么GC是如何让所有的用户线程都停止呢?其使用的是安全点,实现原理如下:

        1、方法代码中被植入的安全点检测入口;

        2. 线程处于安全点状态:线程暂停执行,这个时候线程栈不再发生改变;

        3. JVM 的安全点状态:所有线程都处于安全点状态。

      JVM 支持多种方式来进行线程转储:

        1. JDK 工具, 包括: jstack 工具, jcmd 工具,jconsole,jvisualvm, Java Mission Control 等;

        2. Shell 命令或者系统控制台,比如 Linux 的 kill -3,Windows 的 Ctrl + Break 等;

        3. JMX 技术, 主要是使用 ThreadMxBean。

                    

      fastthread 线程分析:(https://fastthread.io/)

            

    二、内存分析与相关工具

      1、OutOfMemoryError: Java heap space

      创建新的对象时,堆内存中的空间不足以存放新创建的对象产生的原因。其实清楚了原因,问题就很容易解决了:只要增加堆内存的大小,程序就能正常运行。另外还有一些情况是由代码问题导致的:

        超出预期的访问量/数据量:应用系统设计时,一般是有 “容量” 定义的,部署这么多机器,用来处理一定流量的数据/业务。 如果访问量突然飙升,超过预期的阈值,类似于时间坐标系中针尖形状的图谱。那么在峰值所在的时间段,程序很可能就会卡死、并触发 ava.lang.OutOfMemoryError: Java heap space 错误。

        内存泄露(Memory leak):这也是一种经常出现的情形。由于代码中的某些隐蔽错误,导致系统占用的内存越来越多。如果某个方法/某段代码存在内存泄漏,每执行一次,就会(有更多的垃圾对象)占用更多的内存。随着运行时间的推移,泄漏的对象耗光了堆中的所有内存,那么 java.lang.OutOfMemoryError: Javaheap space 错误就爆发了。

      2、OutOfMemoryError: PermGen space/OutOfMemoryError: Metaspace

        java.lang.OutOfMemoryError: PermGen space 的主要原因,是加载到内存中的类数量太多或体积太大,超过了 PermGen 区的大小。

        解决办法:增大 PermGen/Metaspace

          -XX:MaxPermSize=512m

          -XX:MaxMetaspaceSize=512m

        高版本 JVM 也可以:

          -XX:+CMSClassUnloadingEnabled

      3、OutOfMemoryError: Unable to create new native thread

        java.lang.OutOfMemoryError: Unable to create new native thread 错误是程序创建的线程数量已达到上限值的异常信息。

        解决思路:

          1. 调整系统参数 ulimit -a,echo 120000 > /proc/sys/kernel/threads-max

          2. 降低 xss (为jvm启动的每个线程分配的内存大小)等参数

          3. 调整代码,改变线程创建和使用方式

    三、内存分析工具

      1、Eclipse MAT:https://www.cnblogs.com/loong-hon/p/10475143.html

       2、jhat:堆转快照分析工具

      jhat和jmap是对着使用的,jhat用以分析jmap生成的堆转快照文件,但是一般不这么用,一般会使用可视化工具查看。

      使用jhat+快照文件命令后,出现already后即可使用

          

       从上图可以看到端口号为7000,在浏览器访问local host:7000

          

       可以看到分析结果是以包为单位进行分组显示的,分析内存泄漏问题是要会用到其中的Heap Histogram与OQL页签的功能,Heap Histogram可以找到内存中总容量最大的对象,OQL是标准的对象查询语言,使用类似SQL的语法进行查询。

  • 相关阅读:
    groovy execute
    forwarding
    C++实用技巧(一) λcalculus(惊愕到手了欧耶,GetBlogPostIds.aspx) C++博客
    lua与c若干问题 专职C++ C++博客
    [精华] kingate代理服务器指南
    Linux下的静态库和动态库 yg2362 C++博客
    069 问,lua程序设计(第四部分)笔记三,c++调用lua函数 everettjf C++博客
    partition list Groovy builtin to split an array into equal sized subarrays? Stack Overflow
    λcalculus(惊愕到手了欧耶,GetBlogPostIds.aspx) C++博客
    GDB调试使用技巧 专职C++ C++博客
  • 原文地址:https://www.cnblogs.com/liconglong/p/16248749.html
Copyright © 2020-2023  润新知