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

总结
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对象。
内存常用配置参数

- Server端JVM最好将-Xms和-Xmx设为相同 Server端JVM最好将-Xms和-Xmx设为相同值,避免每次垃圾回收完成后JVM重新分配内存,也可以减少垃圾回收次数 值,避免每次垃圾回收完成后JVM重新分配内存,也可以减少垃圾回收次数;
- 注意:tomcat中的配置内存参数可以放在 catalina.sh或者catalina.bat的第二行:
set JAVA_OPTS=%JAVA_OPTS% -server -Xms1800m -Xmx1800m -Xmn600m
XX:PermSize=512M -XX:MaxPermSize=512m -Xss128K -XX:+PrintGCDetails
内存溢出和内存泄漏
- 内存泄漏memory leak :是指程序在申请内存后,无法释放已申请的内存空间,一次内存泄漏似乎不会有大的影响,但内存泄漏堆积后的后果就是内存溢出
- 内存溢出 out of memory :指程序申请内存时,没有足够的内存供申请者使用,或者说,给了你一块存储int类型数据的存储空间,但是你却存储long类型的数据,那么结果就是内存不够用,此时就会报错OOM,即所谓的内存溢出
java对象的引用
包括: 强引用,软引用,弱引用,虚引用
垃圾回收算法
- 引用计数法
给对象中添加一个引用计数器,每当有一个地方引用他时,计数器值就+1,当引用失效时,计数器值就-1;任何时刻计数器为0的对象就是不可能在被使用,判断为不可达,等待gc清理。
这种算法几乎报废因为存在两个问题:
a) 两个对象相互引用, 两个对象相互引用,gc永远都清除不了
b) 引用计数法无法解决多种类型引用的问题 - 复制算法
这种算法会导致50%的内存空间始终空闲浪费! - 标记清除算法
- 标记压缩算法
- 分代算法
垃圾收集器
如果说回收算法是内存回收的方法论,垃圾收集器就是内存回收的具体实现
- Serial收集器
串行收集器是最古老,最稳定以及效率高的收集器,可能会产生较长的停顿,只使用一个线程去回收。
新生代、老年代使用串行回收;新生代复制算法、老年代标记-压缩;垃圾收集的过程中会Stop TheWorld(服务暂停) - ParNew收集器
ParNew收集器其实就是Serial收集器的多线程版本。新生代并行,老年代串行;新生代复制算法、老年代标记-压缩 - Parallel收集器
Parallel Scavenge收集器类似ParNew收集器,Parallel收集器更关注系统的吞吐量。可以通过参数来打开自适应调节策略 - Parallel Old 收集器
- CMS收集器
是一种以获取最短回收停顿时间为目标的收集器。目前很大一部分的Java应用都集中在互联网站或B/S系统的服务端上,这类应用尤其重视服务的响应速度,希望系统停顿时间最短,以给用户带来较好的体验。 - G1收集器
jvm优化知识点升级和配置总结
JDK 1.7 及以往的 JDK 版本中,Java 类信息、常量池、静态变量都存储在 Perm(永久代)里;
JDK 1.8 的对 JVM 架构的改造将类元数据放到本地内存中,另外,将常量池和静态变量放到 Java 堆里。HotSpot VM 将会为类的元数据明确分配和释放本地内存。
JVM启动参数共分为三类
- 标准参数(-),所有的JVM实现都必须实现这些参数的功能,而且向后兼容。例如:-verbose:class(输出jvm载入类的相关信息,当jvm报告说找不到类或者类冲突时可此进行诊断);-verbose:gc(输出每次GC的相关情况);-verbose:jni(输出native方法调用的相关情况,一般用于诊断jni调用错误信息)。
- 非标准参数(-X),默认jvm实现这些参数的功能,但是并不保证所有jvm实现都满足,且不保证向后兼容。例如:-Xms512m;-Xmx512m;-Xmn200m;-Xss128k)。
- 非Stable参数(-XX),此类参数各个jvm实现会有所不同,将来可能会随时取消,需要慎重使用。例如:-XX:PermSize=64m;-XX:MaxPermSize=512m。
jvm 调试工具
jMeter 压力测试工具
下载地址:http://jmeter.apache.org/
动态查看JVM内存的工具
- 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次数 -
新生代垃圾回收统计

-
其他统计查看文章开头文档链接中的资料
- 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
本文深入解析JVM的总体结构,涵盖类加载器、运行时数据区、堆内存管理、垃圾回收算法等内容。详细介绍了JVM启动参数、内存配置、GC类型以及常见调试工具的使用。
399

被折叠的 条评论
为什么被折叠?



