JVM类加载机制
JVM把描述类数据的字节码.Class文件加载到内存,并对数据进行校验、转换解析和初始化,最终形成可以被虚拟机直接使用的java类型,这就是虚拟机的类加载机制。
双亲委派模式:如果一个类加载器收到了类加载请求,它并不会自己先去加载,而是把这个请求委托给父类的加载器去执行,如果父类加载器还存在其父类加载器,则进一步向上委托,依次递归,请求最终将到达顶层的启动类加载器,如果父类加载器可以完成类加载任务,就成功返回,倘若父类加载器无法完成此加载任务,子加载器才会尝试自己去加载,这就是双亲委派模式,即每个儿子都不愿意干活,每次有活就丢给父亲去干,直到父亲说这件事我也干不了时,儿子自己想办法去完成,这就是传说中的双亲委派模式(如果没有任何加载器能加载,就会抛出ClassNotFoundException)
优势:①避免了程序的重复加载;②安全,如果是网络传过来的核心类库,不会再去加载,避免了核心类库被篡改
方法区: static修饰的,常量,字符串,当类加载的时候,方法区就会初始化(所有的线程共享),在web开发的时候,不建议定义太多的常量,GC回收机制不会回收方法区,常量太多导致内存越来越大;
也被称为永久代
堆:所有new出来的对象(成员变量在堆内存中),数组都放在堆内存中,堆的大小可以通过-Xms和-Xmx参数设置
堆分为新生代和老年代,新生代又可以分为Eden区和两块大小相同的from和to区,新生代中存储的是刚创建的对象可以通过-Xmn参数设置新生代的大小,
老年代存储的是经过多次GC后的新生代对象,可以老年代的大小等于Xmx-Xmn
虚拟机栈:方法运行时使用的内存, 比如main方法运行,进入方法栈中执行;栈代码运行完毕,自动释放内存,每个线程私有,互不共享,栈不会产生线程安全问题;
每个方法执行的时候都会创建一个"栈帧",用于存储局部变量(包括参数),对象引用,操作栈,方法入口等信息,每个方法执行到释放的过程就对应真栈帧在虚拟机栈里入栈和出栈的过程,声明周期和线程成相同.
本地方法栈:调用底层C语言,与开发无关
一个方法执行的流程: