首页 > 代码库 > 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内存分配