JVM Run-Time Data Areas & 参数相关
jvm定义了各个运行时数据区:
Run-Time Data Areas
1)The pc Register
2)Java Virtual Machine Stacks
3)Heap
4)Method Area
5)Run-Time Constant Pool
6)Native Method Stacks
运行时数据区: <=== 是一个规范,内存结构是一个实现
1)部分运行时数据区域是在 jvm 创建时创建 销毁时销毁
2)部分运行时数据区域是每个Thread都有一个的,Thread创建时创建,Thread退出时销毁
====> 有一些是共享的 ,有一些是独享的
1)The pc Register 程序计数器 <=== 每个Thread独有
说明:
会占用一小块的内存,其实每个运行时数据区都会占用各自小块内存
用于当前线程所执行的字节码的 行号指示器
用于记录每个线程目前执行到 哪里了:你的代码所对应的哪一条 字节码指令
多个线程并发执行时候,多个线程cpu资源抢占,每一个线程都有自己的程序计数器,进而得到cpu资源时候才知道执行到哪的了
不同的字节码指令做不同的事情,字节码指令是.java文件编译而来的
字节码文件查看方式:javap -verbose HelloWorld.class >> HelloWorld.txt
没有构造器,自带一个默认的空的构造器
2)Java Virtual Machine Stacks <=== 每个Thread独有
存: 用于存放方法里面的一些局部变量
存: frames: 栈帧
A new frame is created each time a method is invoked
A frame is destroyed when its method invocation completes
入栈:方法被调用
出栈:方法执行完
可能会出现的异常:
If the computation in a thread requires a larger Java Virtual Machine stack than is permitted, the Java Virtual Machine throws a StackOverflowError.
即出现情况:线程中的计算需要的 大于 Java Virtual Machine Stacks所允许的
分析:Java Virtual Machine Stacks 存放的东西是与我们的方法相关联的
调用方法时,会为每个方法创建Frame,入栈
方法执行执行完毕,Frame出栈
递归没出口的时候,就会不停的入栈入栈,就会一直压压压,但是Java Virtual Machine Stacks这个的大小是一定的,就会
StackOverflowError
3)Heap 堆 <== 所有 jvm Thread 共享的
创建对象实例 new Student()
存: 对象实例和数组
OutOfMemoryError
If a computation requires more heap than can be made available by the automatic storage management system, the Java Virtual Machine throws an OutOfMemoryError.
即出现情况:计算需要的堆 大于 自动存储管理系统可用的堆
4)Method Area 方法区域 <== Thread 共享的
注意:1.8 Metaspace 元数据 : 存放与.class 相关的一些信息
constant pool,
field and method data,
and the code for methods
and constructors,
即: .class字节码文件会被加载进来
If memory in the method area cannot be made available to satisfy an allocation request, the Java Virtual Machine throws an OutOfMemoryError.
即:如果无法使方法区域中的内存满足分配请求,则Java虚拟机将抛出OutOfMemoryError。
5)Run-Time Constant Pool <== Thread 共享的
6)Native Method Stacks 本地方法栈 <=== 每个Thread独有
Object 类里面许多方法就是navite修饰的,
当调用Navite修饰的方法的时候,每个线程就会有一个本地方法栈
调用底层的,C等
方法:
navite 的
非navite的
前面都是JVM的6大区域,接下来这一个不属于JVM的:
DirectByteBuffer <== java.nio 包
堆外内存 Spark 直接操作内存空间
Spark SQL?
钨丝java
直接操作内存空间,性能好,如果去调用底层源码是可以的
启动起来,就是一个JVM进程
----------------------------------------------------华丽分割线---------------------------------------------------
在这里插入图片描述
JDK7: 永久代
JDK8: Metaspace 元空间
JVM参数类型:
1)标准: 稳定
2)X: 相对变化少的
3)XX : jvm调优的重点
a)boolean : -XX[+/-] name <==启动 禁用
-XX:+UserG1GC
b)非boolean : -XX:name = value
java -Xint -version
java -Xcomp -version
3)XX : jvm调优的重点
启动一个java进程
jps 查看进程IP
【jinfo 】
用于查看正在运行的JVM参数:
语法:jinfo -flag name pid
jinfo -flag PrintGCDetails pid
结果:可以看到是否开启打印GC的参数
jinfo -flag UseG1GC pid
结果:默认是没有开启的,说明JDK8默认不是使用G1作为垃圾回收器的
调整 VM options : -XX:+PrintGCDetails
【元空间大小】
jinfo -flag MetaspaceSize pid
-XX:MetaspaceSize=21807104 大约20M
调整 VM options : -XX:MetaspaceSize=128m
【新生代 老年代】 <== 默认每次GC 年龄会+1
jinfo -flag MaxTenuringThreadshold pid
默认:15
【jinfo 更多】
jinfo -flag InitialHeapSize pid
结果:初始堆大小
jinfo -flag MaxHeapSize pid
结果:最大堆大小
jinfo -flags pid
结果:打出一堆VM参数
【PrintFlags系列】
-XX:+PrintFlagsInital
-XX:+PrintFlagsFinal
jinfo -XX:+PrintFlagsInital -version > temp.txt
结果:
= 表示默认值
:= 表示修改过的
【几个特殊的XX参数】
-Xmx : JVM堆的最大值 -XX:MaxHeapSize 初始化是机器内存的1/4
-Xms : JVM堆的最小值 -XX:InitialHeapSize 初始化是机器内存的1/64
最佳实践:调整为一样的大小,防止内存抖动
调整 VM options : -Xms10m -Xmx10m
jinfo -flag InitialHeapSize pid
结果:初始堆大小
jinfo -flag MaxHeapSize pid
结果:最大堆大小
-Xss -XX:ThreadStackSize
jinfo -flag ThreadStackSize pid
User user = new User();
引用(栈) 对象(堆)
User.class(metaspace)
一流的企业做规范
二流企业做产品
三流企业做产品
四流企业做服务
五流企业做项目
5个异常
5个JVM参数
----------------------------------------------------华丽分割线---------------------------------------------------
选用合适的垃圾回收器很重要
开启ccs就是短指针
每new 一个对象,都会有一个指向自己class的指针,class是在metaspace里面
默认是64位的长指针,考虑性能,可以修改为32位的短指针
【jstat -gc pid 】
打出常用用法: jstat -options
demo:
调整 VM options: -Xms128m -Xmx128m -XX:MetaspaceSize=128m -XX:+UseCompressedClassPoint
jstat -gc pid
结果:关注 CCSC CCSU 是有值的 再就是关注MC MU :metaspace 总共大小,用掉的大小
调整 VM options: -Xms128m -Xmx128m -XX:MetaspaceSize=128m -XX:-UseCompressedClassPoint
jstat -gc pid
结果:关注 CCSC CCSU 均为0,关闭ccs,就不存在ccs的概念了,64位的就是存在metaspace 里面, 这时候再就是关注MC MU,MC = MC(上面) + CCSC(上面)
调整 VM options: -Xms128m -Xmx128m -XX:MetaspaceSize=128m -Xint -XX:-UseCompressedClassPoint
即:默认是comp 编译执行代码,这里修改为解析执行
jstat -gc pid
结果:关注,MC ,会发现比默认的编译执行 总的元空间小
----------------------------------------------------华丽分割线---------------------------------------------------