1、类加载机制
加载-》验证-》准备-》解析-》初始化-》使用-》卸载
1、加载 获取此类的二进制流,将二进制流的静态存储结构转化为方法区的运行时数据结构,然后再内存种生成一个这个类的class对象 作为方法区这个类的各个数据的访问入口
2、验证 主要是用来确保类或接口的二进制表示结构上是正确的,从而保证字节流包含的信息对虚拟机是安全的,对字节流进行安全校验,确保格式正确
类型:文件格式验证 元数据验证 字节码验证 符号验证
3、 准备阶段的任务是为类或者接口的静态字段分配空间,这个阶段不会执行任何的虚拟机字节码指令,在初始化阶段才会显示的初始化这些字段,所以准备阶段不会做这些事情。
4、解析 就是把常量池的符号引用替换成直接引用的过程 有字段解析 接口解析 类解析
5、初始化 JVM才真正开始执行类中定义的Java程序代码:
6、使用
7、卸载 一般条件是 某些线程调用exit方法 这是java管理器允许这些exit操作
2、内存模型
jvm.png程序计数器:较小的内存空间,当前线程执行的字节码的行号指示器;各线程之间独立存储,互不影响;
java 栈:线程私有,生命周期和线程,每个方法在执行的同时都会创建一个 栈帧用于存储局部变量表,操作数栈,动态链接,方法出口等信息。方法的执行就对应着栈帧在虚拟机栈中入栈和出栈的过程;栈里面存放着各种基本数据类型和对象的引用;
本地方法栈:本地方法栈保存的是native方法的信息,当一个JVM创建的线程调用native方法后,JVM不再为其在虚拟机栈中创建栈帧,JVM只是简单地动态链接并直接调用native方法;虚拟机栈为虚拟机执行 Java 方法 (也就是字节码)服务,而本地方法栈则为虚拟机使用到的 Native 方法服务
堆:Java堆是程序员需要重点关注的一块区域,因为涉及到内存的分配(new关键字,反射等)与回收(回收算法,收集器等);此内存区域的唯一目的就是存放对象实例
方法区:也叫永久区,用于存储已被虚拟机加载的类信息、常量、静态变量、即编译后的代码等数据,常量("zdy","123"等),静态变量(static变量)等数据。(jdk1.8已经将方法区去掉了,将方法区移动到直接内存)
运行时常量池:运行时常量池是方法区的一部分,用于存放编译期生成的各种字面("zdy","123"等)和符号引用。
直接内存:不是虚拟机运行时数据区的一部分,也不是java虚拟机规范中定义的内存区域;但也会被频繁使用
1)如果使用了NIO(New Input/Output),这块区域会被频繁使用,在java堆内可以用directByteBuffer对象直接引用并操作;
2) 这块内存不受java堆大小限制,但受本机总内存的限制,可以通过MaxDirectMemorySize来设置(默认与堆内存最大值一样),所以也会出现OOM异常;
3、栈和堆的区别
以栈帧的方式存储方法调用的过程,并存储方法调用过程中基本数据类型的变
量(int、boolean等)以及对象的引
用变量,其内存分配在栈上,变量出了作用域就会自动释放;
栈是私有的
而堆内存用来存储Java中的对象。无论是成员变量,局部变量,还是类变量,
它们指向的对象都存储在堆内存中;
堆是共有的
栈的内存要远远小于堆内存
网友评论