JVM内存模型
字节码和类加载器
- Java Class:Java二进制字节码文件
- ClassLoader:类加载器(双亲委托加载机制)
JVM内存模型
- Method Area(方法区):ClassLoder加载之后的类信息
- Heap(堆):类实例的存放位置
- JVM Stacks(虚拟机栈):类实例的方法相关,存放临时变量
- PC Register(程序计数器):类实例的方法相关,记录程序运行位置
- Native Method Stacks(本地方法栈):类实例的方法相关,为Native方法服务
执行引擎
- Interpreter(解释器):逐行执行程序
- JIT Compiler(即时编译器):对频繁调用的代码,进行编译优化
- GC(垃圾回收):对堆中不再使用的对象进行垃圾回收
本地方法接口
- 本地方法接口:底层操作系统相关
PC Register(程序计数器)
- 作用:记录下一条JVM的执行地址
- 特点:
- 程序计数器是线程私有的
- 唯一一个不会存在内存溢出的内存区域
JVM Stacks(栈)
- 作用:
- 每个线程运行时所需要的内存,称为虚拟机栈
- 每个栈由多个栈帧(Frame)组成,对应这每次方法调用时所占用的内存
- 每个线程只能有一个活动栈帧,对应着正在执行的那个方法
- 结构:
- 辨析:
- GC(垃圾回收)会管理栈内存吗:不会
- 栈内存是否越大越好:不是,可以用-Xss来设置栈内存大小,但是栈内存越大,线程数越少,因为物理内存大小一定
- 栈内的局部变量会受到多线程的影响吗?如果局部变量的作用域未逃离栈,则不会受影响
- 栈内存溢出:
- 栈帧过多导致栈内存溢出
- 栈帧过大导致栈内存溢出
Native Method Stacks(本地方法栈)
- Native底层方法:
- 与操作系统相关,大部分使用C/C++语言编写
- 本地方法区中的方法,在本地方法栈中运行
Heap(堆)
- 作用:通过New关键字,创建对象都会使用堆内存
- 特点:
- 堆空间线程共享,需要考虑线程安全问题
- 有垃圾回收机制
- 堆空间可能会出现内存溢出,-Xmx可以设置堆空间的大小
Method Area(方法区)
- 作用:存储类的结构的相关信息,Field,Method,Code
- 结构:
- 使用永久代(PermGen)实现,JDK1.6版本
- 使用元空间(Metaspace)实现,JDK1.8版本
- 使用永久代(PermGen)实现,JDK1.6版本
- 特点:
- 方法区线程共享
- 方法区在极端情况下也会内存溢出,-XX可以设置方法区的大小
- 常量池:
- 一张表,JVM虚拟机指令根据这张表,找到要执行的,类名/方法名/参数类型/字面量等信息
- 常量池是.class文件中的,当该类被加载时,它的常量池信息会被放入到运行时常量池,并把里面的符号地址转换为真实地址