JVM_基础
JVM参数
在jvm中有很多的参数可以进行设置,这样可以让jvm在各种环境中都能够高效的运行。 绝大部分的参数保持默认即可。
标准参数
-help 、-version 、-D
-D设置系统属性参数
1、运行指定参数
java ‐Dstr=123 TestJVM
2、代码获取方式
String str = System.getProperty("str");
-server与-client参数
可以通过-server或-client设置jvm的运行参数。
1、它们的区别是Server VM的初始堆空间会大一些,默认使用的是并行垃圾回收器,启动慢运行快。
2、Client VM相对来讲会保守一些,初始堆空间会小一些,使用串行的垃圾回收器,它 的目标是为了让JVM的启动速度更快,但运行速度会比Serverm模式慢些。
JVM在启动的时候会根据硬件和操作系统自动选择使用Server还是Client类型的 JVM。
(1)32位操作系统 如果是Windows系统,不论硬件配置如何,都默认使用Client类型的JVM。 如果是其他操作系统上,机器配置有2GB以上的内存同时有2个以上CPU的话默 认使用server模式,否则使用client模式。
(2)64位操作系统 只有server类型,不支持client类型。
java ‐client ‐showversion TestJVM
非标准参数 -X参数
-Xint 、-Xcomp
查询可使用的非标准参数命令
C:\Users\vander>java -X
-Xmixed 混合模式执行 (默认)
-Xint 仅解释模式执行
-Xbootclasspath:<用 ; 分隔的目录和 zip/jar 文件>
设置搜索路径以引导类和资源
-Xbootclasspath/a:<用 ; 分隔的目录和 zip/jar 文件>
附加在引导类路径末尾
-Xbootclasspath/p:<用 ; 分隔的目录和 zip/jar 文件>
置于引导类路径之前
-Xdiag 显示附加诊断消息
-Xnoclassgc 禁用类垃圾收集
-Xincgc 启用增量垃圾收集
-Xloggc:<file> 将 GC 状态记录在文件中 (带时间戳)
-Xbatch 禁用后台编译
-Xms<size> 设置初始 Java 堆大小
-Xmx<size> 设置最大 Java 堆大小
-Xss<size> 设置 Java 线程堆栈大小
-Xprof 输出 cpu 配置文件数据
-Xfuture 启用最严格的检查, 预期将来的默认值
-Xrs 减少 Java/VM 对操作系统信号的使用 (请参阅文档)
-Xcheck:jni 对 JNI 函数执行其他检查
-Xshare:off 不尝试使用共享类数据
-Xshare:auto 在可能的情况下使用共享类数据 (默认)
-Xshare:on 要求使用共享类数据, 否则将失败。
-XshowSettings 显示所有设置并继续
-XshowSettings:all
显示所有设置并继续
-XshowSettings:vm 显示所有与 vm 相关的设置并继续
-XshowSettings:properties
显示所有属性设置并继续
-XshowSettings:locale
显示所有与区域设置相关的设置并继续
-X 选项是非标准选项, 如有更改, 恕不另行通知。
-Xint、-Xcomp、-Xmixed 运行模式
1、-Xint解释模式(interpreted mode)下,-Xint标记会强制JVM执行所有的字节码,当然这 会降低运行速度,通常低10倍或更多。
2、-Xcomp参数与它(-Xint)正好相反,JVM在第一次使用时会把所有的字节码编译成 本地代码,从而带来大程度的优化。 然而,很多应用在使用-Xcomp也会有一些性能损失,当然这比使用-Xint损失的 少,原因是-xcomp没有让JVM启用JIT编译器的全部功能。JIT编译器可以对是否 需要编译做判断,如果所有代码都进行编译的话,对于一些只执行一次的代码就 没有意义了。
3、-Xmixed是混合模式,将解释模式与编译模式进行混合使用,由jvm自己决定,这是 jvm默认的模式,也是推荐使用的模式。
java ‐showversion ‐Xint TestJVM
非标准模式 -XX参数(使用率较高)
主要用于jvm的调优和debug操作
JVM参数调优
关闭手动gc
开启关闭手动gc操作
‐XX:+DisableExplicitGC
初始化/最大堆内存大小
-Xmx2048m:等价于-XX:MaxHeapSize,设置JVM大堆内存为2048M。
-Xms512m:等价于-XX:InitialHeapSize,设置JVM初始堆内存为512M。
java ‐Xms512m ‐Xmx2048m TestJVM
查看JVM默认运行参数
java ‐XX:+PrintFlagsFinal
备注:值的操作符是=或:=,分别代 表默认值和被修改的值。
jps-查看所有Java进程ID
jps -l
jinfo-查看指定进程应用JVM运行参数
jinfo ‐flags 6219
jinfo ‐flag MaxHeapSize 6219
jstat-统计堆内存使用情况(使用率高)
Class类加载统计
jstat ‐class 6219
查看编译统计
jstat -compiler 6219
垃圾回收统计
jstat ‐gc 6219 1000 10
备注:
S0C:第一个Survivor区的大小(KB) S1C:第二个Survivor区的大小(KB) S0U:第一个Survivor区的使用大小(KB) S1U:第二个Survivor区的使用大小(KB) EC:Eden区的大小(KB) EU:Eden区的使用大小(KB) OC:Old区大小(KB) OU:Old使用大小(KB) MC:方法区大小(KB) MU:方法区使用大小(KB) CCSC:压缩类空间大小(KB) CCSU:压缩类空间使用大小(KB) YGC:年轻代垃圾回收次数 YGCT:年轻代垃圾回收消耗时间 FGC:老年代垃圾回收次数 FGCT:老年代垃圾回收消耗时间 GCT:垃圾回收消耗总时间
jmap-内存溢出分析
内存占用过高问题排查
查看内存使用情况
C:\Users\vander>jmap -heap 3760
Attaching to process ID 3760, please wait...
Debugger attached successfully.
Server compiler detected.
JVM version is 25.31-b07
using thread-local object allocation.
Parallel GC with 10 thread(s)
Heap Configuration: #堆内存配置信息
MinHeapFreeRatio = 0
MaxHeapFreeRatio = 100
MaxHeapSize = 4261412864 (4064.0MB)
NewSize = 88604672 (84.5MB)
MaxNewSize = 1420296192 (1354.5MB)
OldSize = 177733632 (169.5MB)
NewRatio = 2
SurvivorRatio = 8
MetaspaceSize = 21807104 (20.796875MB)
CompressedClassSpaceSize = 1073741824 (1024.0MB)
MaxMetaspaceSize = 17592186044415 MB
G1HeapRegionSize = 0 (0.0MB)
Heap Usage: # 堆内存的使用情况
PS Young Generation #年轻代
Eden Space:
capacity = 66584576 (63.5MB)
used = 28971920 (27.629776000976562MB)
free = 37612656 (35.87022399902344MB)
43.511458269254426% used
From Space:
capacity = 11010048 (10.5MB)
used = 10993344 (10.48406982421875MB)
free = 16704 (0.01593017578125MB)
99.84828404017857% used
To Space:
capacity = 11010048 (10.5MB)
used = 0 (0.0MB)
free = 11010048 (10.5MB)
0.0% used
PS Old Generation #年老代
capacity = 177733632 (169.5MB)
used = 2203432 (2.1013565063476562MB)
free = 175530200 (167.39864349365234MB)
1.2397383518275258% used
11586 interned Strings occupying 1033728 bytes.
#查看所有对象,包括活跃以及非活跃的
jmap -histo 3760 | more
#查看活跃对象
jmap -histo:live 3760 | more
内存使用情况dump到文件中
jmap ‐dump:format=b,file=/tmp/dump.dat 3760
jhat命令方式
jhat ‐port 9999 /tmp/dump.dat #浏览器访问
mat工具方式
MAT(Memory Analyzer Tool),一个基于Eclipse的内存分析工具,是一个快速、功能丰 富的JAVA heap分析工具,它可以帮助我们查找内存泄漏和减少内存消耗。使用内存分析 工具从众多的对象中进行分析,快速的计算出在内存中对象的占用大小,看看是谁阻止 了垃圾收集器的回收工作,并可以通过报表直观的查看到可能造成这种结果的对象。
下载地址::https://www.eclipse.org/mat/downloads.php
备注:‐XX:+HeapDumpOnOutOfMemoryError 参数可以在内存溢出的情况下dump文件
jstack-线程执行情况分析
死锁、死循环导致CPU负载过高问题排查。
线程状态
1、初始态(NEW)
创建一个Thread对象,但还未调用start()启动线程时,线程处于初始态。
2、运行态(RUNNABLE),在Java中,运行态包括 就绪态 和 运行态。
(1)就绪态 该状态下的线程已经获得执行所需的所有资源,只要CPU分配执行权就能运 行。 所有就绪态的线程存放在就绪队列中。
(2)运行态 获得CPU执行权,正在执行的线程。 由于一个CPU同一时刻只能执行一条线程,因此每个CPU每个时刻只有一条 运行态的线程。
3、阻塞态(BLOCKED)
当一条正在执行的线程请求某一资源失败时,就会进入阻塞态。 而在Java中,阻塞态专指请求锁失败时进入的状态。 由一个阻塞队列存放所有阻塞态的线程。 处于阻塞态的线程会不断请求资源,一旦请求成功,就会进入就绪队列,等待执 行。
4、等待态(WAITING)
当前线程中调用wait、join、park函数时,当前线程就会进入等待态。 也有一个等待队列存放所有等待态的线程。 线程处于等待态表示它需要等待其他线程的指示才能继续运行。 进入等待态的线程会释放CPU执行权,并释放资源(如:锁)
5、超时等待态(TIMED_WAITING)
当运行中的线程调用sleep(time)、wait、join、parkNanos、parkUntil时,就 会进入该状态; 它和等待态一样,并不是因为请求不到资源,而是主动进入,并且进入后需要其 他线程唤醒; 进入该状态后释放CPU执行权 和 占有的资源。 与等待态的区别:到了超时时间后自动进入阻塞队列,开始竞争锁。
6、终止态(TERMINATED)
线程执行结束后的状态。
查询线程使用情况
jstack 3760 > s.txt
JVM内存模型
JDK1.7
1、年轻代
Young区被划分为三部分,Eden区和两个大小严格相同的Survivor区,其中, Survivor区间中,某一时刻只有其中一个是被使用的,另外一个留做垃圾收集时复制 对象用。
2、年老区
Tenured区主要保存生命周期长的对象,一般是一些老的对象,当一些对象在Young 复制转移一定的次数以后,对象就会被转移到Tenured区。
3、永久区
Perm代主要保存class,method,filed对象,这部份的空间一般不会溢出,除非一次性 加载了很多的类,不过在涉及到热部署的应用服务器的时候,有时候会遇到 java.lang.OutOfMemoryError : PermGen space 的错误,造成这个错误的很大原因 就有可能是每次都重新部署,但是重新部署后,类的class没有被卸载掉,这样就造 成了大量的class对象保存在了perm中,这种情况下,一般重新启动应用服务器可以 解决问题。
JDK1.8
1、堆内存
(1)年轻代
(2)年老区
2、非堆内存
Metaspace
备注:现实使用中,由于永久代内存经常不够用或发生内存泄露,爆出异常 java.lang.OutOfMemoryError: PermGen。基于此,将永久区废弃,而改用元空间,改为了使用本地内存空间。