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是在新生代上面的一段空间 栈上分配
经过逃逸分析以后,编译器根据逃逸分析的结果,对代码进行优化,将没有逃逸的对象放在栈中。
(逃逸分析以后会有三个结果,全局逃逸,参数级逃逸,没有逃逸)
全局逃逸:即一个对象的作用范围逃出了当前方法,例如:对象是一个静态变量 参数逃逸:一个对象被作为方法的参数传递或者被参数引用。)