java - JVM
1. JVM是Java Virtual Machine(Java虚拟机)的缩写,JVM是一种用于计算设备的规范,它是一个虚构出来的计算机,是通过在实际的计算机上仿真模拟各种计算机功能来实现的。
引入Java语言虚拟机后,Java语言在不同平台上运行时不需要重新编译。Java语言使用Java虚拟机屏蔽了与具体平台相关的信息,使得Java语言编译程序只需生成在Java虚拟机上运行的目标代码(字节码),就可以在多种平台上不加修改地运行。
2.结构:
一。类加载器:把类加载到JVM中
二。内存结构:
1)程序计数器:记录下一个要执行的命令的地址
线程私有:每个线程有自己的计数器。
没有内存溢出。
2)虚拟机栈:
每个方法需要的内存称为一个栈帧,执行时先把一个方法的栈帧存入栈,然后再依次调用。栈帧中主要存放了参数,变量,返回地址等信息。
栈结构可以处理方法嵌套的情况下A(){ B(){ C(); }} 此时ABC依次存入栈,然后按CBA的顺序执行。
栈帧中包含:
1.局部变量表: 存放局部变量
2.操作数栈: 执行方法内的代码使用,和虚拟机栈工作原理差不多。
3.动态链接: 运行阶段把符号变为实体对象引用(指针)
4.方法出口: 指向调用方法的位置。比如A方法调用B方法,B结束后可以继续执行A。
常见面试:
虚拟机栈中不涉及垃圾回收
物理内存是一定的,所以栈帧越大,线程数越少。
线程私有保证了线程安全。在递归的时候不会乱。
栈内存溢出:一般是因为栈帧过多(递归忘了写停止条件)
3)本地方法栈:
调用本地方法时使用的栈(native类型的方法,底部为c或者c++)
4)堆:存放对象
线程共享,需要考虑安全问题
垃圾回收的主要工作对象
堆溢出:无限定义对象,或者一个对象无限大(无限添加的ArrayList)
5)方法区:存放方法中的运行时常量池,变量,方法数据,方法结构
线程共享
JVM启动时被创建。逻辑上是堆的一部分(物理上1.8是在堆,1.8后是本地内存的元空间。)
内存溢出:Spring利用ClassWritter产生代理的时候可能会产生
三。执行引擎:执行代码
解释器
即时编译器
垃圾回收(GC):回收堆中不用的对象。
补充:
常量池:本质是一个查询表,为指令提供常量符号,虚拟机指令根据常量池找到需要的方法,参数,符号,常数等。
运行时常量池:方法区中的一个组成部分。当类被加载时,里面的常量池信息会被加载到运行时常量池中,并把符号转化为真实地址(比如常量池中可能有个符号Class,但是只是个字符,在加载后会变成真正的Class类),以便在运行时使用。
类的生命周期:
1.加载:加载class
2.连接:
验证:验证文件正确性
准备:静态变量分配内存,赋java的默认值
解析:静态链接(符号变为实体)加载这个类中用到的其他类。
3.初始化: 变量赋值(程序员给的默认赋值),加载执行静态代码块。 从这里才开始可能运行到java中的代码。
4.使用:
5.卸载