JVM调优学习笔记

本文深入解析JVM的总体结构,涵盖类加载器、运行时数据区、堆内存管理、垃圾回收算法等内容。详细介绍了JVM启动参数、内存配置、GC类型以及常见调试工具的使用。

pdf资料

jvm资料下载地址

JVM总体结构组成:

  1. 类加载器
  2. 运行时数据区
    2.1 方法区
    存放常量池,静态变量,构造方法等。
    不应该在代码中创建过多的静态变量,因为虚拟机启动类加载时就会被放入方法区;且不好回收。
    方法区是线程共享的。
    2.2 堆区
    是存放java实例和对象的地方,是GC主要区域,是线程共享的。
    2.3 栈区
    一个线程会产生一个栈,线程方法会压入栈帧,方法中的变量,参数,运算过程产生的结构数据等也会存在自己的栈帧,线程私有的。
    2.4 PC寄存器
    2.5 本地方法栈
  3. 执行引擎
    3.1 解释器
    3.2 编译器
    3.3 垃圾回收器
  4. 本地接口代码

在这里插入图片描述

总结

1、所有线程共享的内存数据区:方法区,堆。而虚拟机栈,本地方法栈和程序计数器都是线程私有的。
2、存放于栈中的东西如下:
2.1 每个线程包含一个栈区,栈中只保存基础数据类型的对象和自定义对象的引用(不是对象)。对象都存放在堆区中。
2.2 每个栈中的数据(基础数据类型和对象引用)都是私有的,其他栈不能访问。
2.3 方法的形式参数,方法调用完后从栈空间回收
2.4 引用对象的地址,引用完后,栈空间地址立即被回收,堆空间等待GC
3、存放于堆中的东西如下:
3.1 存储的全部是对象,每个对象包含一个与之对应的class信息
3.2 Jvm只有一个堆区(heap)被所有线程共享,堆区中不存放基本类型和对象引用,只存放对象本身
4、存放于方法区中的东西如下:
4.1 存放线程所执行的字节码指令
4.2 跟堆一样.被所有线程共享.方法区包含:所有的class和static变量
4.3 常量池位于方法区中

堆内存

新生代:edon(伊甸园) survivor(辛存者)S1 S2
老年代
永恒代(方法区)

GC的类型:
minor GC
major GC
full GC

EDON 满了后新生代进行 minorGC 去除 无引用对象,计算引用对象的年龄,放入S1或者S2 (其中一个轮流为空),超过一定年龄后放入老年代,老年代满了就会出发major GC (GC 老年代) 或者 full GC (GC 新生代和老年代,会出发STW 现象 stop the world),即所有进程等待GC完成。

是否GC的判断方法,GC roots (根集) 从此出发,可到达的为存活对象,否则为GC对象。

内存常用配置参数

在这里插入图片描述

  1. Server端JVM最好将-Xms和-Xmx设为相同 Server端JVM最好将-Xms和-Xmx设为相同值,避免每次垃圾回收完成后JVM重新分配内存,也可以减少垃圾回收次数 值,避免每次垃圾回收完成后JVM重新分配内存,也可以减少垃圾回收次数;
  2. 注意:tomcat中的配置内存参数可以放在 catalina.sh或者catalina.bat的第二行:
    set JAVA_OPTS=%JAVA_OPTS% -server -Xms1800m -Xmx1800m -Xmn600m
    XX:PermSize=512M -XX:MaxPermSize=512m -Xss128K -XX:+PrintGCDetails

内存溢出和内存泄漏

  1. 内存泄漏memory leak :是指程序在申请内存后,无法释放已申请的内存空间,一次内存泄漏似乎不会有大的影响,但内存泄漏堆积后的后果就是内存溢出
  2. 内存溢出 out of memory :指程序申请内存时,没有足够的内存供申请者使用,或者说,给了你一块存储int类型数据的存储空间,但是你却存储long类型的数据,那么结果就是内存不够用,此时就会报错OOM,即所谓的内存溢出

java对象的引用

包括: 强引用,软引用,弱引用,虚引用

垃圾回收算法

  1. 引用计数法
    给对象中添加一个引用计数器,每当有一个地方引用他时,计数器值就+1,当引用失效时,计数器值就-1;任何时刻计数器为0的对象就是不可能在被使用,判断为不可达,等待gc清理。
    这种算法几乎报废因为存在两个问题:
    a) 两个对象相互引用, 两个对象相互引用,gc永远都清除不了
    b) 引用计数法无法解决多种类型引用的问题
  2. 复制算法
    这种算法会导致50%的内存空间始终空闲浪费!
  3. 标记清除算法
  4. 标记压缩算法
  5. 分代算法

垃圾收集器

如果说回收算法是内存回收的方法论,垃圾收集器就是内存回收的具体实现

  1. Serial收集器
    串行收集器是最古老,最稳定以及效率高的收集器,可能会产生较长的停顿,只使用一个线程去回收。
    新生代、老年代使用串行回收;新生代复制算法、老年代标记-压缩;垃圾收集的过程中会Stop TheWorld(服务暂停)
  2. ParNew收集器
    ParNew收集器其实就是Serial收集器的多线程版本。新生代并行,老年代串行;新生代复制算法、老年代标记-压缩
  3. Parallel收集器
    Parallel Scavenge收集器类似ParNew收集器,Parallel收集器更关注系统的吞吐量。可以通过参数来打开自适应调节策略
  4. Parallel Old 收集器
  5. CMS收集器
    是一种以获取最短回收停顿时间为目标的收集器。目前很大一部分的Java应用都集中在互联网站或B/S系统的服务端上,这类应用尤其重视服务的响应速度,希望系统停顿时间最短,以给用户带来较好的体验。
  6. G1收集器

jvm优化知识点升级和配置总结

JDK 1.7 及以往的 JDK 版本中,Java 类信息、常量池、静态变量都存储在 Perm(永久代)里;
JDK 1.8 的对 JVM 架构的改造将类元数据放到本地内存中,另外,将常量池和静态变量放到 Java 堆里。HotSpot VM 将会为类的元数据明确分配和释放本地内存。

JVM启动参数共分为三类

  1. 标准参数(-),所有的JVM实现都必须实现这些参数的功能,而且向后兼容。例如:-verbose:class(输出jvm载入类的相关信息,当jvm报告说找不到类或者类冲突时可此进行诊断);-verbose:gc(输出每次GC的相关情况);-verbose:jni(输出native方法调用的相关情况,一般用于诊断jni调用错误信息)。
  2. 非标准参数(-X),默认jvm实现这些参数的功能,但是并不保证所有jvm实现都满足,且不保证向后兼容。例如:-Xms512m;-Xmx512m;-Xmn200m;-Xss128k)。
  3. 非Stable参数(-XX),此类参数各个jvm实现会有所不同,将来可能会随时取消,需要慎重使用。例如:-XX:PermSize=64m;-XX:MaxPermSize=512m。

jvm 调试工具

jMeter 压力测试工具
下载地址:http://jmeter.apache.org/

动态查看JVM内存的工具

  1. jps
    Java Virtual Machine Process Status Tool
    功能描述: jps是用于查看有权访问的hotspot虚拟机的进程. 当未指定hostid时,默认查看本机jvm进程,否者查看指定的hostid机器上的jvm进程,此时hostid所指机器必须开启 jstatd服务。 jps可以列出jvm进程lvmid,主类类名,main函数参数, jvm参数,jar名称 等信息
命令用法:jps [options] [hostid]              
options:命令选项,用来对输出格式进行控制              
hostid:指定特定主机,可以是ip地址和域名, 也可以指定具体协议,端 口。              
[protocol:][[//]hostname][:port][/servername]

示例:
在这里插入图片描述
2. jstat

jstat命令可以查看堆内存各部分的使用量,以及加载类的数量。命令的格式如下:
jstat [-命令选项] [vmid] [间隔时间/毫秒] [查询次数]

  • 类加载统计
    在这里插入图片描述
    Loaded:加载class的数量
    Bytes:所占用空间大小
    Unloaded:未加载数量
    Bytes:未加载占用空间
    Time:时间

  • 编译统计
    在这里插入图片描述
    Compiled:编译数量。
    Failed:失败数量
    Invalid:不可用数量
    Time:时间
    FailedType:失败类型
    FailedMethod:失败的方法

  • 垃圾回收统计
    在这里插入图片描述
    S0C:第一个幸存区的大小
    S1C:第二个幸存区的大小
    S0U:第一个幸存区的使用大小
    S1U:第二个幸存区的使用大小
    EC:伊甸园区的大小
    EU:伊甸园区的使用大小
    OC:老年代大小
    OU:老年代使用大小
    MC:方法区大小
    MU:方法区使用大小
    CCSC:压缩类空间大小
    CCSU:压缩类空间使用大小
    YGC:年轻代垃圾回收次数
    YGCT:年轻代垃圾回收消耗时间
    FGC:老年代垃圾回收次数
    FGCT:老年代垃圾回收消耗时间
    GCT:垃圾回收消耗总时间

  • 堆内存统计
    在这里插入图片描述
    NGCMN:新生代最小容量
    NGCMX:新生代最大容量
    NGC:当前新生代容量
    S0C:第一个幸存区大小
    S1C:第二个幸存区的大小
    EC:伊甸园区的大小
    OGCMN:老年代最小容量
    OGCMX:老年代最大容量
    OGC:当前老年代大小
    OC:当前老年代大小
    MCMN:最小元数据容量
    MCMX:最大元数据容量
    MC:当前元数据空间大小
    CCSMN:最小压缩类空间大小
    CCSMX:最大压缩类空间大小
    CCSC:当前压缩类空间大小
    YGC:年轻代gc次数
    FGC:老年代GC次数

  • 新生代垃圾回收统计
    在这里插入图片描述

  • 其他统计查看文章开头文档链接中的资料

  1. jmap
    如果想分析自己的JAVA Application时,可以使用jmap程序来生成heapdump文例
  • jmap -heap 18215
[root@VM_0_12_centos logs]# jmap -heap 18215
Attaching to process ID 18215, please wait...
Debugger attached successfully.
Server compiler detected.
JVM version is 25.231-b11

using thread-local object allocation.
Mark Sweep Compact GC

Heap Configuration:
   MinHeapFreeRatio         = 40
   MaxHeapFreeRatio         = 70
   MaxHeapSize              = 482344960 (460.0MB)
   NewSize                  = 10485760 (10.0MB)
   MaxNewSize               = 160759808 (153.3125MB)
   OldSize                  = 20971520 (20.0MB)
   NewRatio                 = 2
   SurvivorRatio            = 8
   MetaspaceSize            = 21807104 (20.796875MB)
   CompressedClassSpaceSize = 1073741824 (1024.0MB)
   MaxMetaspaceSize         = 17592186044415 MB
   G1HeapRegionSize         = 0 (0.0MB)

Heap Usage:
New Generation (Eden + 1 Survivor Space):
   capacity = 17891328 (17.0625MB)
   used     = 7151232 (6.8199462890625MB)
   free     = 10740096 (10.2425537109375MB)
   39.97038118131868% used
Eden Space:
   capacity = 15925248 (15.1875MB)
   used     = 6768472 (6.454917907714844MB)
   free     = 9156776 (8.732582092285156MB)
   42.501517087834365% used
From Space:
   capacity = 1966080 (1.875MB)
   used     = 382760 (0.36502838134765625MB)
   free     = 1583320 (1.5099716186523438MB)
   19.468180338541668% used
To Space:
   capacity = 1966080 (1.875MB)
   used     = 0 (0.0MB)
   free     = 1966080 (1.875MB)
   0.0% used
tenured generation:
   capacity = 39657472 (37.8203125MB)
   used     = 30705216 (29.28277587890625MB)
   free     = 8952256 (8.53753662109375MB)
   77.42605479239826% used

28169 interned Strings occupying 2942056 bytes.
  • jmap -dump:format=b,file=a.dump
[root@VM_0_12_centos logs]# jmap -dump:format=b,file=chenk.dump 18215
Dumping heap to /usr/local/tomcat/apache-tomcat-9.0.30/logs/chenk.dump ...
Heap dump file created
评论
成就一亿技术人!
拼手气红包6.0元
还能输入1000个字符
 
红包 添加红包
表情包 插入表情
 条评论被折叠 查看
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值