Java中的堆(heap)和栈(stack)内容解析------夜空中最亮的星

Java把内存划分为两种:一种是栈内存,一种是堆内存。

栈内存

定义:主要保存在函数中定义的一些基本类型的变量和对象的引用变量。

如:
基本类型变量:String str1 = "
测试";
引用变量:String str2 = new String("
测试");

str1和str2 都是保存在栈内存中的。

当定义一个变量时,java就在栈中为这个变量分配内存空间,当超过变量的作用域后(如一个界面finish();一些变量不会再用到),

java会自动释放掉该变量所分配的内存空间。

堆内存

定义:用来存放由new创建的对象和数组,在堆中分配的内存,由java虚拟机自动垃圾回收器(GC:Garbage Collection)来管理。

如:

String str = new String("测试");   "测试"两个字就存在有堆分配的内存中。


引用变量

定义:在堆中存储了一个数组或对象后,还可以在栈中定义一个特殊的变量,让栈中这个变量的取值等于数组或对象在堆内存

中的首地址,栈中的这个变量就成了数组或对象的引用变量。


堆栈比较

栈内存:

栈内存存取速度比堆要快,仅次于寄存器,栈数据可以共享;

存在栈中的数据大小与生存期必须是确定的,缺乏灵活性;

栈中主要存放一些基本数据的变量(byte,int,short,long,float,double,boolean,char)和对象句柄;

堆内存:

堆是一个运行时数据区,类的对象从中分配空间,这些对象通过new、newarray、anewarray和

multianewarray等指令建立,它们不需要程序代码来显示的释放。

堆是由垃圾回收器来负责的,堆的优势可以动态的分配内存大小,生存期也不必实现告诉编辑器,因为它是运行时动态分配内存的,

java的垃圾回收器会自动收走这些不在使用的数据。但缺点是,由于要在运动时动态分配内存,存取速度较慢。


public class MyMain {
	
	static MyMain mMain = null;
	
	public static void main(String[] args){
		mMain = new MyMain();
		mMain.testHeapAndStack();
	}
	
	/**
	 * 测试堆和栈
	 */
	public void testHeapAndStack(){
		String a = "6";
		String b = "6";
		String c = new String("6");			
		String d = new String("6");

		System.out.println("a == b ..."+(a==b));	
		System.out.println("a == c ..."+(a==c));
		System.out.println("a.equals(c)..."+(a.equals(c)));
		System.out.println("c == d..."+(c == d));
		
		/**
		 * 结果:
		 * a == b ...true
		 * a == c ...false
		 * a.equals(c)...true
		 * c == d...false 
		 * 
		 * 
		 * 解析:
		 * 
		 * 注意: a==b 比较的是a和b所指向的内存地址是否相等
		 * 		 a.equals(b) 比较的是a和b所指向的值是否相等
		 * 
		 * 编译器先处理String a = "6";首先在栈中创建一个变量为a的引用,然后在栈中查找是否有"6"这个值,
		 * 如果没找到,就新创建一个存储值为3的内存。接下来编译器继续处理String b = "6";
		 * 因为在栈中已存在6这个值,便将b直接指向6这个值,所以a和b同时指向了一个存储值为6的内存。 
		 * 所以判断"a == b"的结果为true。
		 * 
		 * c = new String("6"); 会在堆中创建一个存储值为6的内存,在栈内存中创建一个String类型对象的引用变量
		 * c,然后栈中c的值为堆中存储值为6的内存的内存地址。对于"a == c"来说,a指向的值在栈内存中,c指向的值在
		 * 堆内存中,所以a肯定不等于c,结果为false       
		 * 
		 *d = new String("6");原理同c一样,对于"c == d"来说,"new"故名思意,是"新"的意思,虽然在堆中存在
		 *存储值为6的内存,由于new的存在,所以会在堆中开辟一个新的内存存储6,c和d的内存地址不同,所以
		 *c不可能等于d。                                                                         
		 * 
		 * 对于c.equals(d),变量c指向的值为 6,变量d指向的值为6,所以c和d指向的值都为6,所以c.equals(b)结果为true
		 * 
		 */
		
	}

}





  • 1
    点赞
  • 1
    收藏
    觉得还不错? 一键收藏
  • 1
    评论
评论 1
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值