Java数据存储

概况

本文主要介绍Java中数据的存储位置及机制。

概念

在Java中,程序分为6个存储区域来存放变量以及代码占用的内存

  1. 寄存器Register最快的存储区,位于CPU内部,程序无法控制
  2. Stack
    • 位于通用RAM中,通过栈指针可以从处理器那里直接获得
    • 栈指针若向下移动则分配新的内存,若向上移动则释放内存
    • 一种快速的分配方法,仅次于寄存器
    • 基本类型的数据对象的引用
  3. Heap
    • 存放由new创建的对象和数组
    • JVM自动管理
  4. 静态存储区域Static Field
    • 在固定的位置存放应用程序运行时一直存在的数据
    • 生命周期随着程序编译而产生,程序结束而回收
  5. 常量池Constant Pool
    • JVM虚拟机必须为每个被装载的类型维护一个常量池
    • 常量池是该类型所用到常量的一个有序集合,包括直接常量(基本类型,String)和其它类型、字段和方法的符号引用
  6. 非RAM存储区:数据存活于程序之外,不受程序控制,在没有程序的时候依然存在。如流对象持久化对象

堆内存存储与栈内存存储比较

存储方式

相同点

堆与栈都是用于程序中的数据在RAM(内存)上的存储区域,并且Java自动地管理堆和栈,不能人为去直接设置

不同点

  1. 存储数据类型栈内存中存放局部变量(基本数据类型和对象引用),而堆内存用于存放对象(实体)
  2. 存储速度栈内存的存储分配与清理速度更快于堆,并且栈内存的存储速度仅次于直接位于处理器中的寄存器
  3. 灵活性:由于栈内存与堆内存存储机制的不同,堆内存灵活性更优于栈内存

存储机制

  • 栈内存被要求存放在其中的数据的大小、生命周期必须是已经确定的
  • 堆内存可以被虚拟机动态的分配内存大小,无需事先知道编译器的数据的大小、生命周期等相关信息

存储数据类型

栈内存

  • Java中,变量的类型通常分为基本数据类型变量对象引用变量
  • 8种基本数据类型实际上存储的是一组位数不同的二进制数据,除此之外,布尔型只有truefalse两种值
  • 对象引用变量存储的实际是其所关联(指向)对象在内存中的内存地址,而内存地址实际上也是一串二进制的数据
  • 局部变量的大小可以确定,会在其自身所属方法(或代码块)执行完毕后,被自动释放

堆内存

  • Java中使用关键字new通过调用类的构造函数,从而得到该类的对象
  • 对象类型数据在程序编译期并不会在内存中进行创建和存储工作,而是在程序运行期才根据需要进行动态的创建和存储
  • 对象由堆内存进行存储管理

栈内存中存储的数据可以实现数据共享

  • 好处节约内存空间,避免反复向内存中加入同样的值
  • 对于字符串而言,如果是编译器已经创建好(直接使用双引号定义)的就存储在常量池中,如果是运行期new出来的)才能确定存储在堆中
  • 对于equals()相等的字符串,在常量池中永远只有一份,在堆中可以有多份
  • 常量池与栈内存一样,也可以实现数据共享
  • 成员变量的数据存储于堆中该成员变量所属的对象里
  • 堆内存中存放的变量会进行默认初始化,而栈内存中存放的变量却不会

参考方案

  1. java中数据的5种存储位置(堆与栈)
  2. Java中数据存储方式、栈机制与引用的关系
  3. Android群英传
  4. Java系列笔记(3)-Java内存区域和GC机制
  5. Jvm内存模型