文章目录
1、JVM介绍
JVM 有Server、Client两种,我们讲的重点是 Server
Windows是32位的,默认就是Client模式的
32位,2G,2core 及以上的是Server模式,低于这个配置的是Client模式
Java三种类型:解释型(int)、编译型(comp)、混合型(mixed mode)
现在默认就是混合型的
C:\Users\Administrator>java -version
java version "1.8.0_131"
Java(TM) SE Runtime Environment (build 1.8.0_131-b11)
Java HotSpot(TM) 64-Bit Server VM (build 25.131-b11, mixed mode) #混合型
java -Xint -version
C:\Users\Administrator>java -Xint -version
java version "1.8.0_131"
Java(TM) SE Runtime Environment (build 1.8.0_131-b11)
Java HotSpot(TM) 64-Bit Server VM (build 25.131-b11, interpreted mode)
java -Xcomp -version
C:\Users\Administrator>java -Xcomp -version
java version "1.8.0_131"
Java(TM) SE Runtime Environment (build 1.8.0_131-b11)
Java HotSpot(TM) 64-Bit Server VM (build 25.131-b11, compiled mode)
JVM参数类型主要是三大类:
- 标准:稳定的
- X: 相对变化较少的
- XX: 相对来说变化多的,不稳定的,但对JVM调优来说是重点,也是我们讲的重点
对于XX来说,又有两类
a):boolean
标准写法:-XX:+UseG1GC -XX:-UseG1GC GC垃圾回收器
-XX:[+/-] name +就是启用,-就是禁用
jps => 获取pid
jinfo -flag name pid
b):非boolean
标准写法:-XX:name=value -XX:k=v
可以在IDEA里面设置,-XX:MetaspaceSize=128m
jinfo -flag MetaspaceSize 3840
JDK7–>JDK8的最大一个变化,就是永久代到Metaspace
2、jinfo/PrintFlags
2.1 jinfo
jinfo + 回车,查看帮助信息
jinfo -flag 打印一个JVM的参数值
jinfo -flags 打印所有的JVM参数的值
为方便查看JVM信息,先创建一个类,执行该类,然后在DOS窗口中,查看运行中的Class的JVM信息
package com.ruozedata.jvm;
public class JvmDemo {
public static void main(String[] args) throws InterruptedException {
System.out.println("zuozedata");
Thread.sleep(100000);
}
}
jinfo -flag PrintGCDetails pid(进程号),打印pid的JVM信息
C:\Users\Administrator> jinfo -flag PrintGCDetails 1324
-XX:-PrintGCDetails #可以看到-,并没有开启
启用
再次执行
C:\Users\Administrator> jinfo -flag PrintGCDetails 1324
-XX:+PrintGCDetails #这里变为了+,表示启用了
jinfo -flag UseG1GC 6100
C:\Users\Administrator> jinfo -flag UseG1GC 6100
-XX:-UseG1GC #说明jdk8不是使用G1GC
jinfo -flag MetaspaceSize 1012
也可以通过在IDEA程序里面,修改大小,添加这一行 -XX:MetaspaceSize=128m
C:\Users\Administrator> jinfo -flag MetaspaceSize 1012
-XX:MetaspaceSize=21807104
-flag MaxTenuringThreshold 7384
新生代到老年代有个年龄控制,每次是+1,默认是15次
C:\Users\Administrator> jinfo -flag MaxTenuringThreshold 7384
-XX:MaxTenuringThreshold=15
jinfo -flag InitialHeapSize 7492
查看堆初始值
C:\Users\Administrator> jinfo -flag InitialHeapSize 7492
-XX:InitialHeapSize=268435456
jinfo -flag MaxHeapSize 7492
查看堆最大值
C:\Users\Administrator> jinfo -flag MaxHeapSize 7492
-XX:MaxHeapSize=4276092928
打印所有Flag的JVM参数设置
jinfo -flags 7492
C:\Users\Administrator> jinfo -flags 7492 >version.txt
2.2 PrintFlags
PrintFlags 系列
-XX:+PrintFlagsInitial
-XX:+PrintFlagsFinal
查看系统所有的Flag参数选项,一般放到一个txt文件,然后选择我们需要修改的参数项
java -XX:+PrintFlagsInitial >version.txt
有两大类
= 默认值
:= 修改过的
3、几个特殊的参数
几个特殊的XX参数
-Xmx :jvm的最大值 -XX:MaxHeapSize 的简写
-Xms :jvm的最小值 -XX:InitialHeapSize 的简写
-Xss -XX:ThreadStackSize 的简写 Stack 栈
jinfo -flag MaxHeapSize pid
jinfo -flag InitialHeapSize pid
(这两个值一般设置成一样)
IDEA修改参数 -Xms10m -Xmx10m 一般设置一样的值
没有设置的时候,为什么两个不一样呢?
通过指向上面的命令:
-Xms 大概200m,-Xmx 大概3G
系统一般有个默认分配:-Xms 总内存的1/64 -Xmx 总内存的1/4
4、JVM运行时数据区(Run-Time Data Areas)
Java虚拟机定义了在程序执行期间使用的各种运行时数据区域。
其中一些数据区域是在Java虚拟机启动时创建的,只有当Java虚拟机退出时才会销毁。
其他数据区域是每个线程。每个线程的数据区域在线程创建时创建,在线程退出时销毁。
-
The pc Register 程序计数器
一句话:存放的是当前正在执行的一个指令的地址 -
Java Virtual Machine Stacks JVM栈
当创建线程的时候会创建一个jvm栈。
干什么事情呢?像抛出的异常信息,就是JVM栈里面打印出来的 -
Heap 堆
是所有JVM线程所共享的
装class的实例(对象实例),数组
在jvm启动时创建,由GC来管理他
User user =new User();
等号左边的叫引用(Stack) ,右边的叫对象(创建出来的这个存放在 Heap) -
Method Area 方法区,在1.8里面就是一个Metaspace
方法区也是所有JVM线程所共享的。
存什么东西呢?
它存储的是class的信息,
比如运行时常量池、字段和方法数据,
以及方法和构造函数的代码,
包括在类和实例初始化以及接口初始化中使用的特殊方法 -
Native Method Stacks 本地方法栈
为Native方法服务
5、JVM内存模型
主要分为两大区域 heap、非heap(mataspace)
图中的Perm不是堆内存,是永久代
图中的Virtaul则是各区域还未被分配的内存,即最大内存-当前分配的内存
heap:
Young:
Eden
Survivor: S0,S1大小是一样的,同一时间只有一个启动,相当于主备
S0: from
S1: to
Old
大多数new出来的,首先分配到Eden区,如果Eden区满了,就进行垃圾回收,
如果对象还活着,就到S0区,
每一次GC,Eden到S0区的一个捣腾过程,会有一个年龄+1的操作,如果到了15,就进入Old
所以上面,这部分 就是GC的关键所在,怎么让他高效,就要采用一个合适的GC
非heap(metaspace)
ccs :CompressedClassPointers 压缩类指针
短指针32:如果开启ccs,启用短指针;如果短指针没有启用,ccs是不存在的
每new出来的一个东西,都有一个指向自己class的一个指针
长指针64:默认
CodeCache:JIT或者JNI有关系,有没有编译本地代码,编译了就在这里面