源码 → 字节码文件
classloader装载
类的加载过程:
-
装载
查找并装载类型的二进制数据
-
链接
verify, 验证确保class文件字节流中信息符合当前虚拟机要求
prepare,为类变量分配内存并将其初始化为默认初始值
①类变量(也叫静态变量): 被 static 修饰的变量; 其他所有类型的变量都属于 类成员变量
②类变量初始化默认值, 而常量(static final)被直接赋予用户希望的值
resolve,把常量池中的符号引用转换为内存中的直接引用
-
初始化
按语句执行顺序对类对象进行初始化;执行类构造器方法;把静态变量初始化为正确初始值;
启动类加载器(Bootstrap ClassLoader):
c/c++实现的,嵌套在JVM内部;
加载Java核心库;
只加载包名为java,javax,sun等开头的类
用户自定义类加载器:
继承自ClassLoader
扩展类加载器(Extentsion ClassLoader):
java实现;
父类加载器是启动加载器;
系统类加载器(AppClassLoader):
父类加载器是扩展类加载器;
该类加载是程序中默认的类加载器,一般来说,java应用的类都是由它来完成加载
双亲委派机制
某个特定的类加载器在接到加载类的请求时,首先将加载任务委托给父类加载器,依次递归,如果父类加载器可以完成类加载任务,就成功返回;只有父类加载器无法完成此加载任务时,才自己去加载.
避免类的重复加载;对java核心源代码的保护(沙箱安全机制);
JVM系统线程(hotspot):
虚拟机线程
周期任务线程
周期任务线程
GC线程
编译线程
信号调度线程
-
确定类变量的初始值。在类加载的准备阶段,JVM 会为类变量初始化零值,这时候类变量会有一个初始的零值。如果是被 final 修饰的类变量,则直接会被初始成用户想要的值。
-
初始化入口方法。当进入类加载的初始化阶段后,JVM 会寻找整个 main 方法入口,从而初始化 main 方法所在的整个类。当需要对一个类进行初始化时,会首先初始化类构造器(),之后初始化对象构造器()。
-
初始化类构造器。JVM 会按顺序收集类变量的赋值语句、静态代码块,最终组成类构造器由 JVM 执行。
-
初始化对象构造器。JVM 会按照收集成员变量的赋值语句、普通代码块,最后收集构造方法,将它们组成对象构造器,最终由 JVM 执行。
数据类型:
基本类型:变量保存原始值
引用类型:变量保存引用值,对象本身放在这个引用值所表示的地址的位置
堆与栈:
栈是运行时的单位,存的是:基本数据类型,对重对象的引用
堆是存储的单位,存的是:对象
Java对象大小:
java中一个空oject对象的大小是8byte,java栈保存引用需要4byte
Object ob = new Object();
//Object对象(8byte)+引用(4byte)=12byte
Class NewObject{
int count;
boolean flag;
Object ob;
}
// 空对象大小(8byte)+int大小(4byte)+Boolean大小(1byte)+空Object引用的大小(4byte)=17byte
//但是因为Java在对对象内存分配时都是以8的整数倍来分,因此此对象的大小为24byte
年轻代(yong generation)
年老代(old generation)
持久代(permanent generation)
Scavenge GC
Full GC
调优总结:
年轻代大小选择:
响应时间优先的应用:
吞吐量优先的应用:
年老代大小选择: