一起学JVM(GC可视化工具Visual GC)

2021-12-07 15:44:52 浏览数 (1)

导读

  • 众所周知,JVM(java虚拟机)运行着我们的java程序。java本身提供了自带工具VisualVM来帮助我们查看JVM的运行情况,下面主要介绍GC的可视化插件-Visual GC

java版本

  • 1.8.0_281

工具

  • VisualVM 的 Visual GC 插件

面板解读

space 空间模块
  • Space — 空间主要描述空间的变化
    • Metaspace —  元空间
    • Old — 老年代
    • Eden — 伊甸园区
    • S0 — 存活0区
    • S1 — 存活1区

方框区:所占空间大小 空白区:未使用空间 颜色区:已使用空间

Graphs 曲线图模块
  • Graphs — 曲线图主要描述时间轴上,的空间变化
    • Compile Time — ☆类型☆:编译时长曲线图
      • compiles —  单位:当前编译累计次数(次)
      • ms- 单位:当前编译花费累计时长(毫秒)
    • Class Loader Time — ☆类型☆:类加载时长
      • loaded — 单位:当前累计已加载个数(个)
      • unloaded — 单位:当前未加载个数(个)
      • ms- 单位:当前类加载累计花费时长(毫秒)
    • GC Time — ☆类型☆:垃圾回收时长曲线图
      • collections — 单位:当前垃圾回收累计次数(次)
      • Last Cause:CMS Initial Mark — 最近GC原因:CMS回收初始标记
      • Eden Space — ☆类型☆:伊甸园区时长曲线图
        • (v1, v2): v3 — v1:最大分配内存(M) v2:初始分配内存(M) v3:当前占用内存(M)
        • collections — 单位:当前GC累计次数(次)
        • ms- 单位:当前GC累计花费时长(毫秒)
      • Survivor 0 — ☆类型☆:存活0区时长曲线图
        • (v1, v2): v3 — v1:最大分配内存(M) v2:初始分配内存(M) v3:当前占用内存(M)
      • Survivor 1 — ☆类型☆:存活1区时长曲线图
        • (v1, v2): v3 — v1:最大分配内存(M) v2:初始分配内存(M) v3:当前占用内存(M)
      • Old Gen — ☆类型☆:老年区时长曲线图
        • (v1, v2): v3 — v1:最大分配内存(M) v2:初始分配内存(M) v3:当前占用内存(M)
        • collections — 单位:当前GC累计次数(次)
        • ms- 单位:当前GC累计花费时长(毫秒)
      • Metaspace — ☆类型☆:元空间时长曲线图
        • (v1, v2): v3 — v1:最大分配内存(M) v2:初始分配内存(M) v3:当前占用内存(M)
Histogram 矩形图模块
  • Histogram — 矩形图
    • Parameters — 参数
      • Tenuring Threshold —  晋升阈值,达到该阈值则从新生代进入老年代 单位:新生代GC后存活次数
      • Max Tenuring Threshold — 最大晋升阈值 单位:新生代GC后存活次数
      • Desired Survivor Size — 期望存活空间大小,是当前存活空间大小的一半 单位:bytes
      • Current Survivor Size — 当前存活空间大小 单位:bytes
    • Histogram 0-15 — 例如1:新生代GC过1次的对象

最大15次新生代GC的原因是:对象的对象头(object header)中markword区域的GC标记信息(分代年龄)占4bit,也就是15

安装 Visual GC

  • 打开 VisualVM

linux终端执行下面的命令行

代码语言:javascript复制
jvsualvm
  • 进入 VisualVM
  • 导航栏 -> 工具 ->  插件
在线安装
  • 可用插件 ->  Visual GC  ->  安装
  • 下一步
  • 我接受 ->  安装
  • 由于需要翻墙,所以此安装方式失败,会报错,所以请参考下面的离线安装方式。
离线安装
  • 访问visualVM官网  ->  Download
  • https://visualvm.github.io/index.html
  • plugins offline
  • 回到 VisualVM  查看JDK版本
  • 导航栏 ->  帮助 ->  关于
  • 详细信息
  • 关键信息:1.8.0_281 和 8u131
  • 回到下载页面 131-291  和 8u131 来确定下载版本
  • 点击 Visual GC  进行下载
  • 下载插件文件完毕
  • 回到 VisualVM
  • 导航栏 -> 工具 ->  插件 -> 已下载 ->  添加插件 -> 插件下载本地路径 ->  确定  
  • 勾选 Visual GC -> 安装 ->  下一步
  • 插件安装成功!
  • 已安装(1)
  • 重启 VisualVM  插件就生效啦!

idea 安装 visualVM Launcher

  • idea导航栏 -> File -> Plugins -> Marketplace -> VisualVM Launcher
  • Other Settings -> VisualVM Launcher -> 选择jdk的jvisualvm的目录

使用

  • 运行以下java代码来查看GC情况
代码语言:javascript复制
package zhai.jvm;

import java.util.ArrayList;
import java.util.List;
import java.util.concurrent.TimeUnit;

/**
 * -Xms10m -Xmx10m -XX: UseConcMarkSweepGC -XX: PrintGCDateStamps -XX: PrintGCDetails
 */
public class TestJVM {
    byte[] data = new byte[1024*100];
    public static void main(String[] args) throws InterruptedException {
        List<TestJVM> list = new ArrayList<>();
        while (true) {
            list.add(new TestJVM());
            TimeUnit.SECONDS.sleep(1);
        }
    }
}
  • 代码解读

一个死循环,每隔1s,往集合内放入一个1K大小的数据。

  • jvm参数解读

-Xms 设置初始化内存 -Xmx 设置最大分配内存 -XX: UseConcMarkSweepGC 使用CMS GC -XX: PrintGCDateStamps 打印GC 时间戳 -XX: PrintGCDetails 打印GC详情

  • idea配置jvm参数
  • Edit Configurations
  • 运行项目
  • 打开 VisualVM 选择本地运行的java程序 -> Visual GC
  • 观察 Visual GC

随着时间的推移,对象不断的从新生代被转移到老年代,并且不能被Full CG,最后先导致老年代满了,然后很快新生代也满了,导致系统报错 OutOfMemoryError: Java heap space

代码语言:javascript复制
Exception in thread "main" java.lang.OutOfMemoryError: Java heap space
	at zhai.jvm.TestJVM.<init>(TestJVM.java:11)
	at zhai.jvm.TestJVM.main(TestJVM.java:16)

最后

  • 通过可视化工具Visual GC,来帮助我们观察堆内存的运行情况,配置JVM参数,反复测试来达解决内存泄露问题,降低GC次数,提高系统的稳定性。

0 人点赞