Jvm简介
什么是jvm

Java执行流程

JVM是Java平台无关的保障

Jvm规范
- Jvm规范是针对编译出来的*.class文件的
Jvm能够实现开发语言无关

Jvm规范主要内容
字节码指令集
Class文件格式
数据类型和值
运行时数据区
栈帧
类库
特殊方法
异常
虚拟机启动 加载 链接 初始化
。。。
特殊方法

类库

Class文件


javap可以反编译class字节码文件,生成可阅读的汇编语言

ClassFile结构

Java内存分配
JVM简化架构图

PC寄存器:1. 存储指向下一条指令的地址。 2. 线程私有,每创建一个线程会创建一个寄存器。3. 执行本地方法的时候值为undefined。4. 一块比较小的内存空间,没有规定OutOfMemoryError区域,不会溢出。
Java栈:1. 由一系列帧组成。2. 线程私有。3. 帧用来保存一个方法的:局部变量,操作数栈,常量池指针,动态链接,方法返回值。3. 每一次方法调用创建一个帧,并且压入栈中,退出方法时,销毁栈帧中的内容。
Java堆:1. 用来存放应用系统创建的对象和数组,所有线程共享Java堆。2. GC主要管理堆空间。3. 运行期动态分配内存大小,自动进行GC。4. 效率相对较慢。
方法区: 1. 所有线程共享,用来保存装载类的结构信息。2. 通常和元空间关联在一起。
运行时常量池:

本地方法栈:

交互关系:
堆内存
- 通过new 创建的对象都放入堆内存
- 动态分配内存,自动GC
- GC主要回收堆内存, 对于分代GC来说堆也是分代的
堆结构:

新生代用来放新分配的对象。新生代经过垃圾回收,没有回收掉的对象进入老年代
老年代存储对象的年龄比新生代的年龄大的多
老年代一般储存一些大对象
整个堆大小:新生代+老年代
新生代:Eden+存活区

对象的内存布局
对象=对象头+实例数据+对齐填充
对象头:

实例数据:

对齐填充: 占位符到八字节
对象定位
使用句柄定位变量:
优点:对象移动时,只需要修改句柄里的指针,不需要修改reference
缺点: 运行速度慢,因为需要两次定位

使用指针定位对象:
优点:速度快

Java堆参数
Xms. Xmx:最小堆大小 最大堆大小 以及初始堆大小,默认物理内存为1/64。必须是1024倍数,最小为1mb。
设置xms

使用-XX:MinHeapSize, -XX:InitialHeapsize 和 -XX:MaxHeapSize来分别设置最大最小和初始堆大小

-Xmn用来设置新生代大小: 设置的小,经常执行GC。 设置的大,仅仅执行full GC
-XX:UseConcMarkSweepGC 用来开启CMS GC
-Xlog:gc+heap=debug 每一次GC后都打印堆信息

- -XX:+HeapDumpOnOutOfMemoryError: OOM时导出堆到文件
- -XX:HeapDumpPath:导出OOM的路径

- XX:NewRatio:老年代和新生代的比值。如果xms=xmx且有xmn,不用设置该参数。-XX:NewRatio=3 意思是新生代/老年代=1/3

-Xss:决定函数调用深度