## **数据类型**
Java虚拟机中,数据类型可以分为两类:**基本类型**和**引用类型**。
* **基本类型**
基本类型的变量保存原始值,他代表的值就是数值本身。
包括:byte,short,int,long,char,float,double,boolean,returnAddress
* **引用类型**
引用类型的变量保存的是引用对象的地址。
包括:**类类型**,**接口类型**和**数组**
## **内存结构**
JVM 内存分配结构对于不同的JDK版本有不同的结构类型,下图
![](https://img.kancloud.cn/a8/8b/a88baa83c4dd59df5ee096882452ab5c_1033x497.jpg)
![](https://img.kancloud.cn/23/01/23014c39a2c56bdd53d32fdf8046756f_1037x495.jpg)
![](https://img.kancloud.cn/48/9d/489dd4da84b2e9f6cd717659cd695542_1033x490.jpg)
观察上图发现,JVM内存结构主要包括
* 堆
* 虚拟机栈
* 本地方法栈
* 方法区(JDK7之后版本就去除了)
* 程序计数器
## **堆**
java堆是java虚拟机所管理的内存中最大的一块,该内存区域的唯一目的就是存放对象实例。JDK7后,字符串常量池从永久代中剥离出来,存放在堆中。
堆被划分成两个不同的区域:新生代 ( Young )、老年代 ( Old )。新生代 ( Young ) 又被划分为三个区域:Eden、From Survivor、To Survivor。
![](https://img.kancloud.cn/1d/38/1d38f608fc262a5f2c8a4aad60d1d88d_802x274.jpg)
## **虚拟机栈**
虚拟机栈描述的是Java方法执行的内存模型:每个方法在执行的同时都会创建一个栈帧(Stack Frame)用于存储局部变量表、操作数栈、动态链接、方法出口等信息。
![](https://img.kancloud.cn/2e/58/2e58ac317ab2fb59cccf2663d7557204_594x572.jpg)
* **局部变量表**
用于存放**方法参数**和**方法内部定义的局部变量**
* **操作栈**
用于存放计算操作所需的值以及结果值
* **动态链接**
每个栈帧都包含一个指向运行时常量池中该栈帧所属方法的引用,持有这个引用是为了支持方法调用过程中的动态连接
* **返回地址**
用于保存方法执行完成后返回的地址
> 栈是运行时的单位,而堆是存储的单位;栈主要解决程序如何处理数据,堆解决的是数据存储的问题,即数据怎么放、放在哪儿。
## **本地方法栈**
本地方法栈与虚拟机栈所发挥作用非常相似,它们之间的区别不过是虚拟机栈为虚拟机执行Java方法服务,而本地方法栈则为虚拟机使用到的native方法服务
## **程序计数器**
程序计数器是一块较小的内存空间,它可以看作是当前线程所执行的字节码的行号指示器。
## **方法区**
它用于存储已被虚拟机加载的类信息、常量、静态变量、即时编译器编译后的代码等数据。
## **常量池**
常量池中主要存放两类数据,一是字面量、二是符号引用,JDK6常量池位于方法区中,JDK7之后常量池存放在堆中。
* **字面量**:比如String类型的字符串值或者定义为final类型的常量的值
* **符号引用**:
1. 类或接口的全限定名(包括他的父类和所实现的接口)
2. 变量或方法的名称
3. 方法的描述信息(参数个数、参数类型、方法返回类型等等)
4. 变量的描述信息(变量的返回值)