原文地址:http://yanwushu.sinaapp.com/java_data_storage/
Java程序在运行时需要为1系列的值或对象分配内存,这些值都存在甚么地方?用甚么样的数据结构存储?这些数据结构有甚么特点?本文试图说明此命题的皮毛之皮毛。
概念
对Java,有6个不同的、用于数据存储的概念,他们是:
1. 寄存器( register),是最快的存储区,位于处理器内部。由于寄存器的数量极为有限,所以寄存器由编译器根据需求进行分配。http://www.wfuyu.com没法使用Java代码使用寄存器中的存储空间,或说:在Java开发的层面上,寄存器的操作已被封装。
2. 栈( stack),位于通用 RAM。存取速度快,仅次于寄存器。栈指针若向下移动,则分配新的内存;若向上移动,则释放那些内存。创建程序时候, JAVA 编译器必须知道存储在栈内所有数据的确切大小和生命周期,由于它必须生成相应的代码,以便上下移动栈指针,进而分配和释放内存。由于栈的这类存储特性,所以某些数据存在栈中,比如对象援用和基础类型的变量值;但是有些数据是不合适存到栈中的,比如对象的实例。
3. 堆( heap),1个运行时数据区,位于 RAM。堆中的空间是动态分配的,所以,不需要知道数据的大小和生命周期。因此,在堆里存储数据有很大的灵活性。Java对象的实例和数组放在这里。堆中的过期对象由GC负责回收。堆的存取速度较慢。
4. 静态存储( static storage),RAM中1片固定的位置。存储静态数据,这些数据在程序中用static关键字修饰。
5. 常量存储( constant storage),常量值通常直接寄存在程序代码内部,这样做是安全的,由于它们永久不会被改变。
6. 非 RAM存储。如果数据完全存活于程序以外,那末它可以不受程序的任何控制,在程序没有运行时也能够存在。
栈和静态存储的数据同享
用1个案例理解,假定定义:
int a = 3;
int b = 3 ;
编译器先处理 int a = 3 ;首先它会在栈中创建1个变量为a 的援用,然后查找栈中是不是有 3 这个值,如果没找到,就将3 寄存进来,然后将 a 指向 3 。接着处理 int b = 3 ;在创建完 b 的援用变量后,由于在栈中已有 3 这个值,便将 b 直接指向 3 。这样,就出现了 a 与 b 同时均指向 3 的情况。这时候,如果再令 a=4 ;那末编译器会重新搜索栈中是不是有 4 值,如果没有,则将 4 寄存进来,并令 a 指向 4 ;如果已有了,则直接将 a 指向这个地址。因此 a 值的改变不会影响到 b 的值。要注意这类数据的同享与两个对象的援用同时指向1个对象的这类同享是不同的,由于这类情况 a 的修改其实不会影响到 b, 它是由编译器完成的,它有益于节省空间。而1个对象援用变量修改了这个对象的内部状态,会影响到另外一个对象援用变量。
数据同享对静态数据一样。