首页 > 代码库 > Java内存分配
Java内存分配
一般Java在内存分配时会涉及到以下区域:
◆寄存器:我们在程序中无法控制
◆栈:存放基本类型的数据和对象的引用,但对象本身不存放在栈中,而是存放在堆中(new 出来的对象)
◆堆:存放用new产生的数据
◆静态域:存放在对象中用static定义的静态成员
◆常量池:存放常量
◆非RAM存储:硬盘等永久存储空间
栈:方法中定义的一些基本类型的变量数据和对象(和形式参数)的引用变量都在栈内存中分配,栈内存中的局部变量随着方法的消失而消失。存在栈中的数据可以共享
堆:存放由new创建的对象和数组,由GC管理。栈中定义引用变量,其取值等于数组或对象在堆内存中的首地址。引用变量在程序运行到其作用域之外后被释放。而数组和对象不会,他们只有在没有引用变量指向它的时候才会被GC在适当时机回收。
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 | class BirthDate { private int day; private int month; private int year; public BirthDate(int d, int m, int y) { day = d; month = m; year = y; } } public class Test{ public static void main(String args[]){ int date = 9; Test test = new Test(); test.change(date); BirthDate d1= new BirthDate(7,7,1970); } public void change1(int i){ i = 1234; } } |
下面分析一下代码执行时候的变化:
1. main方法开始执行:int date = 9; date局部变量,基础类型,引用和值都存在栈中。
2. Test test = new Test(); test为对象引用,存在栈中,对象(new Test())存在堆中。
3. test.change(date); i为局部变量,引用和值存在栈中。当方法change执行完成后,i就会从栈中消失。
4. BirthDate d1= new BirthDate(7,7,1970);d1 为对象引用,存在栈中,对象(new BirthDate())存在堆中,其中d,m,y为局部变量存储在栈中,且它们的类型为基础类型,因此它们的数据也存储在栈中。 day,month,year为成员变量,它们存储在堆中(new BirthDate()里面)。当BirthDate构造方法执行完之后,d,m,y将从栈中消失。
5.main方法执行完之后,date变量,test,d1引用将从栈中消失,new Test(),new BirthDate()将等待垃圾回收。
常量池:常量池指在编译期被确定,并被保存在已编译的.class文件中的数据。
除了包含代码中所定义的各种基本类型和对象型的常量值(final)还包含一些以文本形式出现的符号引用,比如:
◆类和接口的全限定名;
◆字段的名称和描述符;
◆方法的名称和描述符;
String类型在编译期已经创建好(直接用双引号定义的)的就存储在常量池中,如果是运行期(new出来的)才能确定的就存储在堆中。
Java内存分配