Java中堆、栈、常量池等概念解析


Java 中堆中堆中堆中堆、、、、栈栈栈栈、、、、常量池等概念解析常量池等概念解析常量池等概念解析常量池等概念解析 1. 寄存器寄存器寄存器寄存器::::最快的存储区最快的存储区最快的存储区最快的存储区, 由编译器根据需求进行分配由编译器根据需求进行分配由编译器根据需求进行分配由编译器根据需求进行分配,我们在程序中无法控制我们在程序中无法控制我们在程序中无法控制我们在程序中无法控制. 2. 栈栈栈栈::::存放基本类型的变量数据和对象的引用存放基本类型的变量数据和对象的引用存放基本类型的变量数据和对象的引用存放基本类型的变量数据和对象的引用,,,,但对象本身不存放在栈中但对象本身不存放在栈中但对象本身不存放在栈中但对象本身不存放在栈中,,,,而是存放在堆而是存放在堆而是存放在堆而是存放在堆 ((((new 出来的对象出来的对象出来的对象出来的对象))))或者常量池中或者常量池中或者常量池中或者常量池中((((字符串常量对象存放在常量池中字符串常量对象存放在常量池中字符串常量对象存放在常量池中字符串常量对象存放在常量池中。)。)。)。) 3 1. 寄存器寄存器寄存器寄存器::::最快的存储区最快的存储区最快的存储区最快的存储区, 由编译器根据需求进行分配由编译器根据需求进行分配由编译器根据需求进行分配由编译器根据需求进行分配,我们在程序中无法控制我们在程序中无法控制我们在程序中无法控制我们在程序中无法控制. 2. 栈栈栈栈::::存放基本类型的变量数据和对象的引用存放基本类型的变量数据和对象的引用存放基本类型的变量数据和对象的引用存放基本类型的变量数据和对象的引用,,,,但对象本身不存放在栈中但对象本身不存放在栈中但对象本身不存放在栈中但对象本身不存放在栈中,,,,而是存放在堆而是存放在堆而是存放在堆而是存放在堆 ((((new 出来的对象出来的对象出来的对象出来的对象))))或者常量池中或者常量池中或者常量池中或者常量池中((((字符串常量对象存放在常量池中字符串常量对象存放在常量池中字符串常量对象存放在常量池中字符串常量对象存放在常量池中。)。)。)。) 3. 堆堆堆堆::::存放所有存放所有存放所有存放所有 new 出来的对象出来的对象出来的对象出来的对象。。。。 4. 静态域静态域静态域静态域::::存放静态成员存放静态成员存放静态成员存放静态成员((((static 定义的定义的定义的定义的)))) 5. 常量池常量池常量池常量池::::存放字符串常量和基本类型常量存放字符串常量和基本类型常量存放字符串常量和基本类型常量存放字符串常量和基本类型常量((((public static final )。)。)。)。 6. 非非非非 RAM 存储存储存储存储::::硬盘等永久存储空间硬盘等永久存储空间硬盘等永久存储空间硬盘等永久存储空间 这里我们主要关心栈这里我们主要关心栈这里我们主要关心栈这里我们主要关心栈,,,,堆和常量池堆和常量池堆和常量池堆和常量池,,,,对于栈和常量池中的对象可以共享对于栈和常量池中的对象可以共享对于栈和常量池中的对象可以共享对于栈和常量池中的对象可以共享,,,,对于堆中的对象对于堆中的对象对于堆中的对象对于堆中的对象 不可以共享不可以共享不可以共享不可以共享。。。。栈中的数据大小和生命周期是可以确定的栈中的数据大小和生命周期是可以确定的栈中的数据大小和生命周期是可以确定的栈中的数据大小和生命周期是可以确定的,,,,当没有引用指向数据时当没有引用指向数据时当没有引用指向数据时当没有引用指向数据时,,,,这个数这个数这个数这个数 据就会消失据就会消失据就会消失据就会消失。。。。堆中的对象的由垃圾回收器负责回收堆中的对象的由垃圾回收器负责回收堆中的对象的由垃圾回收器负责回收堆中的对象的由垃圾回收器负责回收,,,,因此大小和生命周期不需要确定因此大小和生命周期不需要确定因此大小和生命周期不需要确定因此大小和生命周期不需要确定,,,,具具具具 有很大的灵活性有很大的灵活性有很大的灵活性有很大的灵活性。。。。 对于字符串对于字符串对于字符串对于字符串::::其对象的引用都是存储在其对象的引用都是存储在其对象的引用都是存储在其对象的引用都是存储在栈中的栈中的栈中的栈中的,,,,如果是编译期已经创建好如果是编译期已经创建好如果是编译期已经创建好如果是编译期已经创建好(直接用双引号定直接用双引号定直接用双引号定直接用双引号定 义的义的义的义的)的就存储在常量池中的就存储在常量池中的就存储在常量池中的就存储在常量池中,,,,如果是运行期如果是运行期如果是运行期如果是运行期((((new 出来的出来的出来的出来的))))才能确定的就存储在堆中才能确定的就存储在堆中才能确定的就存储在堆中才能确定的就存储在堆中。。。。对于对于对于对于 equals 相等的字符串相等的字符串相等的字符串相等的字符串,,,,在常量池中永远只有一份在常量池中永远只有一份在常量池中永远只有一份在常量池中永远只有一份,,,,在堆中有多份在堆中有多份在堆中有多份在堆中有多份。。。。 如以下代码如以下代码如以下代码如以下代码:::: Java 代码代码代码代码 String s1 = "china"; String s2 = "china"; String s3 = "china"; String ss1 = new String("china"); String ss2 = new String("china"); String ss3 = new String("china"); 这里解释一下黄色这这里解释一下黄色这这里解释一下黄色这这里解释一下黄色这 3 个箭头个箭头个箭头个箭头,,,,对于通过对于通过对于通过对于通过 new 产生一个字符串产生一个字符串产生一个字符串产生一个字符串((((假设为假设为假设为假设为””””china ””””))))时时时时,,,,会会会会 先去常量池中查找是否已经有了先去常量池中查找是否已经有了先去常量池中查找是否已经有了先去常量池中查找是否已经有了””””china ””””对象对象对象对象,,,,如果没有则在常量池中创建一个此字符串如果没有则在常量池中创建一个此字符串如果没有则在常量池中创建一个此字符串如果没有则在常量池中创建一个此字符串 对象对象对象对象,,,,然后堆中再创建一个常量池中此然后堆中再创建一个常量池中此然后堆中再创建一个常量池中此然后堆中再创建一个常量池中此””””china ””””对象的拷贝对象对象的拷贝对象对象的拷贝对象对象的拷贝对象。。。。这也就是有道面试题这也就是有道面试题这也就是有道面试题这也就是有道面试题:::: String s = new String( ““““xyz ””””); 产生几个对象产生几个对象产生几个对象产生几个对象????一个或两个一个或两个一个或两个一个或两个,,,,如果常量池中原来没有如果常量池中原来没有如果常量池中原来没有如果常量池中原来没有””””xyz ””””, 就是两个就是两个就是两个就是两个。。。。 对于基础类型的变量和常量对于基础类型的变量和常量对于基础类型的变量和常量对于基础类型的变量和常量::::变量和引用存储在变量和引用存储在变量和引用存储在变量和引用存储在栈中栈中栈中栈中,,,,常量存储在常量池中常量存储在常量池中常量存储在常量池中常量存储在常量池中。。。。 如以下代码如以下代码如以下代码如以下代码:::: Java 代码代码代码代码 int i1 = 9; int i2 = 9; int i3 = 9; public static final int INT1 = 9; public static final int INT2 = 9; public static final int INT3 = 9; 对于成员变量和局部变量对于成员变量和局部变量对于成员变量和局部变量对于成员变量和局部变量::::成员变量就是方法外部成员变量就是方法外部成员变量就是方法外部成员变量就是方法外部,,,,类的内部定义的变量类的内部定义的变量类的内部定义的变量类的内部定义的变量;;;;局部变量就是局部变量就是局部变量就是局部变量就是 方法或语句块内部定义的变量方法或语句块内部定义的变量方法或语句块内部定义的变量方法或语句块内部定义的变量。。。。局部变量必须初始化局部变量必须初始化局部变量必须初始化局部变量必须初始化。。。。 形式参数是局部变量形式参数是局部变量形式参数是局部变量形式参数是局部变量,,,,局部变量的数据存在于栈内存中局部变量的数据存在于栈内存中局部变量的数据存在于栈内存中局部变量的数据存在于栈内存中。。。。栈内存中的局部变量随着方法的栈内存中的局部变量随着方法的栈内存中的局部变量随着方法的栈内存中的局部变量随着方法的 消失而消失消失而消失消失而消失消失而消失。。。。 成员变量存储在堆中的对象里面成员变量存储在堆中的对象里面成员变量存储在堆中的对象里面成员变量存储在堆中的对象里面,,,,由垃圾回收器负责回收由垃圾回收器负责回收由垃圾回收器负责回收由垃圾回收器负责回收。。。。 如以下代码如以下代码如以下代码如以下代码:::: Java 代码代码代码代码 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; } 省略省略省略省略 get,set 方法方法方法方法……………………………… } 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; } } 对于以上这段代码对于以上这段代码对于以上这段代码对于以上这段代码,,,,date 为局部变量为局部变量为局部变量为局部变量,,,,i,d,m,y 都是形参为局部变量都是形参为局部变量都是形参为局部变量都是形参为局部变量,,,,day ,,,,month ,,,,year 为为为为 成员变量成员变量成员变量成员变量。。。。下面分析一下代码执行时候的变化下面分析一下代码执行时候的变化下面分析一下代码执行时候的变化下面分析一下代码执行时候的变化:::: 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() 将等待垃圾回收将等待垃圾回收将等待垃圾回收将等待垃圾回收。。。。 本 篇 文 章 来 源 于本 篇 文 章 来 源 于本 篇 文 章 来 源 于本 篇 文 章 来 源 于 :::: 开 发 学 院开 发 学 院开 发 学 院开 发 学 院 http://edu.codepub.com 原 文 链 接原 文 链 接原 文 链 接原 文 链 接 :::: http://edu.codepub.com/2010/1127/27493.php
还剩2页未读

继续阅读

下载pdf到电脑,查找使用更方便

pdf的实际排版效果,会与网站的显示效果略有不同!!

需要 15 金币 [ 分享pdf获得金币 ] 1 人已下载

下载pdf

pdf贡献者

5cai

贡献于2011-05-22

下载需要 15 金币 [金币充值 ]
亲,您也可以通过 分享原创pdf 来获得金币奖励!
下载pdf