概况
本文主要介绍Java中数据的存储位置及机制。
概念
在Java中,程序分为6个存储区域来存放变量以及代码占用的内存
- 寄存器:
Register
,最快的存储区,位于CPU内部,程序无法控制 - 栈:
Stack
- 位于通用
RAM
中,通过栈指针可以从处理器那里直接获得 - 栈指针若向下移动则分配新的内存,若向上移动则释放内存
- 一种快速的分配方法,仅次于寄存器
- 基本类型的数据和对象的引用
- 位于通用
- 堆:
Heap
- 存放由
new
创建的对象和数组 - 由
JVM
自动管理
- 存放由
- 静态存储区域:
Static Field
- 在固定的位置存放应用程序运行时一直存在的数据
- 生命周期随着程序编译而产生,程序结束而回收
- 常量池:
Constant Pool
JVM
虚拟机必须为每个被装载的类型维护一个常量池- 常量池是该类型所用到常量的一个有序集合,包括直接常量(基本类型,
String
)和其它类型、字段和方法的符号引用
- 非RAM存储区:数据存活于程序之外,不受程序控制,在没有程序的时候依然存在。如流对象和持久化对象
堆内存存储与栈内存存储比较
存储方式
相同点
堆与栈都是用于程序中的数据在RAM
(内存)上的存储区域,并且Java
会自动地管理堆和栈,不能人为去直接设置
不同点
- 存储数据类型:栈内存中存放局部变量(基本数据类型和对象引用),而堆内存用于存放对象(实体)
- 存储速度:栈内存的存储分配与清理速度更快于堆,并且栈内存的存储速度仅次于直接位于处理器中的寄存器
- 灵活性:由于栈内存与堆内存存储机制的不同,堆内存灵活性更优于栈内存
存储机制
- 栈内存被要求存放在其中的数据的大小、生命周期必须是已经确定的
- 堆内存可以被虚拟机动态的分配内存大小,无需事先知道编译器的数据的大小、生命周期等相关信息
存储数据类型
栈内存
- 在
Java
中,变量的类型通常分为基本数据类型变量和对象引用变量 - 8种基本数据类型实际上存储的是一组位数不同的二进制数据,除此之外,布尔型只有
true
和false
两种值 - 对象引用变量存储的实际是其所关联(指向)对象在内存中的内存地址,而内存地址实际上也是一串二进制的数据
- 局部变量的大小可以确定,会在其自身所属方法(或代码块)执行完毕后,被自动释放
堆内存
Java
中使用关键字new
通过调用类的构造函数,从而得到该类的对象- 对象类型数据在程序编译期并不会在内存中进行创建和存储工作,而是在程序运行期才根据需要进行动态的创建和存储
- 对象由堆内存进行存储管理
栈内存中存储的数据可以实现数据共享
- 好处:节约内存空间,避免反复向内存中加入同样的值
- 对于字符串而言,如果是编译器已经创建好(直接使用双引号定义)的就存储在常量池中,如果是运行期(
new
出来的)才能确定存储在堆中 - 对于
equals()
相等的字符串,在常量池中永远只有一份,在堆中可以有多份 - 常量池与栈内存一样,也可以实现数据共享
- 成员变量的数据存储于堆中该成员变量所属的对象里
- 堆内存中存放的变量会进行默认初始化,而栈内存中存放的变量却不会