目录
概述
字节码文件生成:首先Java源代码文件(.java后缀)会被Java编译器编译为字节码文件(.class后缀),然后由JVM中的类加载器加载各个类的字节码文件,加载完毕之后,交由JVM执行引擎执行。
在整个程序执行过程中,JVM会用一段空间来存储程序执行期间需要用到的数据和相关信息,这段空间一般被称作为Runtime Data Area(运行时数据区),也就是我们常说的JVM内存。因此,在Java中我们常常说到的内存管理就是针对这段空间进行管理(如何分配和回收内存空间)。
执行引擎是将字节码指令解释、编译成操作系统可以识别的本地机器指令。
JVM内存分配
根据 JVM 规范,JVM 内存共分为虚拟机栈、堆、方法区、程序计数器、本地方法栈五个部分。
各个分区介绍
| 名称 | 特征 | 作用 | 配置参数 | 异常 |
|---|---|---|---|---|
| 程序计数器 | 占用内存小,线程私有 | 字节码行号指示器 | 无 | 无 |
| 虚拟机栈 | 线程私有,使用连续的内存空间 | java方法存储的内存模型,存储局部变量表、操作数栈、动态链接、方法出口等 | -Xss | OOM,stackOverFlow |
| 本地方法栈 | 线程私有 | 为虚拟机使用到的本地方法服务,方便与外界环境交互 | 无 | OOM,stackOverFlow |
| 堆 | 线程共享 | 保存对象实例,所有对象实例都要在堆上分配 |
-Xmn -Xms -Xmx |
OOM java heap space |
| 方法区 | 线程共享 | 存储已被虚拟机加载的类信息,常量,静态变量,即时编译器编译后的代码等数据 |
-XX:PermSize: 16M -XX:MaxPermSize 64M |
1.7 OOM PermGen space 1.8 OOM Metaspace |
| 运行时常量池 | 方法区的一部分 | 字面量及符号引用 |
1.7和1.8区别
其实,移除永久代的工作从JDK 1.7就开始了。JDK 1.7中,存储在永久代的部分数据就已经转移到Java Heap或者Native Heap。但永久代仍存在于JDK 1.7中,并没有完全移除,譬如符号引用(Symbols)转移到了native heap;字面量(interned strings)、类的静态变量转移到了Java heap。
JDK1.8和JDK1.7的jvm内存最大的区别是, 在1.8中方法区是由元空间(元数据区)来实现的,常量池移到堆中.
1.8不存在方法区,将方法区的实现给去掉了,而是在本地内存中,新加入元数据区(元空间).
元空间: 存储.class 信息, 类的信息,方法的定义,静态变量等.而常量池放到堆里存储