JVM体系

》类加载机制
》编译与反编译
》JVM内存结构
》JVM内存模型
》垃圾回收
》JVM参数及调优
》JVM对象模型


class文件的格式

是一种8位字节的二进制文件流,各个数据项按照顺序紧密的从前向后排列

魔数

数值为0xCAFEBABE
class文件开头的四个字节,判断这个文件是不是class格式的文件的标志

minor_version 和major_version

在魔数的后面,分别为主版本和次版本号
高版本的JVM可以识别低版本的class文件,低版本的JVM不能识别高版本的class,会抛出        java。lang。UnsupportedClassVersionError

常量池

字面量符号引用

包含类中的所有信息的描述

基本的JVM的构造图

堆(heap)

作用:主要是创建对象和数组(数组也是对象)
结构:新生代(1/3)老年代(2/3)    
新生代:Eden,From Survivor0,To Servivor1
老年代:Tenured

分别的作用:
Eden :创建大部分的新生对象
From:经过了一个GC存活下来的对象
To:和 From 进行交换的对象位置
Tenured:经过了15个GC以后留下来的对象

创建的对象的基本构造

对象头,实例数据,对齐填充

栈(stack)

主要的作用:一个栈帧是基本的单位,一个方法一个栈。
主要结构:方法出口,操作数栈,局部变量表,程序计数器

方法出口:除了main的栈帧,其余的均有,主要是找到这个运行的方法要返回的位置
局部变量表:存储这个方法中的的局部变量的值
操作数栈:存储一些变量的操作过过程
程序计数器:记录这个操作数运行的步数,在java的文件的编译在反编译以后,会有 针对的指令

补充理解:一个方法,就在栈中使用一块栈帧,创建线程,一个一个运行,从被调用的方法开始,直到main方法结束

本地方法栈(Native Method Stack)

主要是存储java调用本地方法时(为c语言所写),为本地方法提高存放变量堆栈
方法区(Method Area)-元空间
主要是存储存储常量(final),静态变量(static)类,运行常量池
字面量:存储的主要是数值,就是一些定义的数据等
符号引用:主要是对方法,变量和对象等的类型的描述

java的直接内存

*直接内存并不是虚拟机运行时数据区的一部分,也不是Java 虚拟机规范中定义的内存区域,跟三种IO的NIO有关,跟JVM没有多大的关系
主要是为了放置NIO的运行内存。由DirectByteBuffer对象的引用来管理这个区域

堆和栈的区别

栈存放的是局部变量,堆存放的实体
栈内存的更新速度高于堆内存
栈内存的生命周期一结束就会释放,而堆会被gc不定时回收

java对象分配策略

尝试栈上分配
尝试TLAB分配
是否可以直接进入老年区
eden分配

java中的对象一定在堆上面吗?

no

原因:

TLAB分配(Thread Local Allocation Buffer)
TLAB是在新生代上面的一段空间
栈上分配

经过逃逸分析以后,编译器根据逃逸分析的结果,对代码进行优化,将没有逃逸的对象放在栈中。

(逃逸分析以后会有三个结果,全局逃逸,参数级逃逸,没有逃逸)

全局逃逸:即一个对象的作用范围逃出了当前方法,例如:对象是一个静态变量
参数逃逸:一个对象被作为方法的参数传递或者被参数引用。)