您的位置:首页 > 编程语言 > Java开发

java内存基础

2015-08-18 19:37 281 查看
和java相关的内存区域有:代码段、数据段、栈内存、堆内存和常量池。





代码段:存放在硬盘加载的代码;

数据段:用来存储静态成员;

栈内存:存放局部变量,包括引用类型的地址(不是地址和c中指针类似,执行堆中对象)和基本数据类型变量的值;

堆内存:存放对象和常量池;

常量池:存放常量。

关于常量池:不仅仅存放常量,也能存放一部分实现常量池的引用类型变量的值。除了浮点类型的包装类型 Integer Long等和String类型都实现了,常量池,他们的一部数据可以保存在常量池中。

1 除了浮点类型的包装类型变量的值:

在【-128,127】这个区间里,没有new直接赋值的时候,值会保存在常量池中,其他的会保存在常量池之外的堆内存中;



public static void main(String[] args) {
		Integer n1=1;
		Integer n2=1+1-1;
		System.out.println(n1==n2);

	}



上面这段程序返回结果为true;因为Integer实现了常量池,符合条件的值会保存在常量池中,n1=1 会在常量池中查找有没有Integer 1,有就把1的引用给n1,没有直接创建一个1.n2的值会被优化器优化为最终结果,再去内存查找,发现存在了1,直接让n2指向这个 1.因此n1和n2指向同一块内存,两个引用内存的值相等。




public class Test {

	public static void main(String[] args) {
		Integer n1=128;
		Integer n2=128;
		System.out.println(n1==n2);

	}

}


这段代码返回为false;n1>127,所以去常量池之外的栈内存创建了一个对象,n2同样创建了一个对象。



2 String类型,类似于上面的包装类型,没有new直接赋值则保持在常量池,new过之后保持在其他堆内存中。不过,String没有new但是出现了用变量连接值的情况,也会直接去常量池之外的堆内存创建对象。

public static void main(String[] args) {
		String s="ab";
		String s1="abc";
		String s2="ab"+"c";
		String s3=s1;
		String s4=s+"c";		
		System.out.println(s1==s2);
		System.out.println(s1==s3);
		System.out.println(s1==s4);

	}


前两个返回true,最后一个返回false;

s1的值保存在常量池中,s2的值经过优化器优化结果为"abc",然后去常量池查找有“abc”吗,结果找到了,直接指向“abc”,所以s1 s2指向同一块内存。

s1的引用直接赋值给s3,所以s3和s1的值相同。

s4中出现了变量,优化器不会去优化,在程序运行时候,直接创建新对象,所以s4指向了其他地方。



最后一点就是:基本类型和引用类型存储上最大的区别是 基本类型只占一块内存,引用类型占两块内存。


内容来自用户分享和网络整理,不保证内容的准确性,如有侵权内容,可联系管理员处理 点击这里给我发消息
标签: