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 MaxTenuringThreshold 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 ,会发现比默认的编译执行 总的元空间小

----------------------------------------------------华丽分割线---------------------------------------------------

原文地址:https://www.cnblogs.com/liuge36/p/12614722.html