今天看了些基础的东西,主要涉及到java的内存方面的知识,想问一下,下面的说法哪些是对的,哪些是错的?
1.对象的引用(例如Class a = new .....的那个“a”)是存储在“栈”上的;
2.基本类型的引用(例如int a;的那个“a”)是存储在“栈”上的;
3.所有类的对象由new生成,并存储在“堆”上;
4.所有的基本类型(例如int i = 3;的那个“3”)是存储在“栈”上的;
5.Object obj[];中的引用“obj”是生成于“栈”上的;
6.Object obj[] = new Object[10];中的“new Object[10]”是存储在“堆”上的;
7.int i[];中的引用“i”是生成于“栈”上的;
8.int i[] = new int[10];中的“new int[10];”是存储在“栈”上的;
9.标注static的类和变量被存放于特定的静态存储区(仍旧在RAM上);
10.栈上开辟内存的速度比堆要快,堆上开辟内存的速度要比静态存储区快;
11
String ss = " abc ";//ss:堆栈;" abc ":栈
ss = ss.trim();//"abc":栈
ss = ss + "abc"+123;//123:栈;"abc":同上为栈上同一块位置;结果"abcabc123":栈
///结论,此三行代码共在堆上建立了一个引用,在栈上建立了4个不同位置区域用以存储值。
请问,上述代码中所注释的关于内存的分配说明对么????问题多了点,其中有些我可以肯定,但有些就不确定了,盼望基础扎实的前辈们能解答一下。
1.对象的引用(例如Class a = new .....的那个“a”)是存储在“栈”上的;
2.基本类型的引用(例如int a;的那个“a”)是存储在“栈”上的;
3.所有类的对象由new生成,并存储在“堆”上;
4.所有的基本类型(例如int i = 3;的那个“3”)是存储在“栈”上的;
5.Object obj[];中的引用“obj”是生成于“栈”上的;
6.Object obj[] = new Object[10];中的“new Object[10]”是存储在“堆”上的;
7.int i[];中的引用“i”是生成于“栈”上的;
8.int i[] = new int[10];中的“new int[10];”是存储在“栈”上的;
9.标注static的类和变量被存放于特定的静态存储区(仍旧在RAM上);
10.栈上开辟内存的速度比堆要快,堆上开辟内存的速度要比静态存储区快;
11
String ss = " abc ";//ss:堆栈;" abc ":栈
ss = ss.trim();//"abc":栈
ss = ss + "abc"+123;//123:栈;"abc":同上为栈上同一块位置;结果"abcabc123":栈
///结论,此三行代码共在堆上建立了一个引用,在栈上建立了4个不同位置区域用以存储值。
请问,上述代码中所注释的关于内存的分配说明对么????问题多了点,其中有些我可以肯定,但有些就不确定了,盼望基础扎实的前辈们能解答一下。
特别说明8,此时用的是int,在栈内,如果是Integer则在堆上八种基本类型(包括它们的数组)和对象的引用都放在栈里
所有用new产生的对象都放在堆中
如:int a = 3; //1
int arr = new int[](1,2,3); //2
假设按1、2顺序执行,由于int为8种基本类型之一,所以对于1编译器先在栈内建立一个变量为a的引用,再在栈内寻找有无存储数据为3的内存单元,有则将a指向该内存地址无则新建一个,并将a指向它,对于2,new int[](1,2,3)可看成重复三次1过程,最后arr指向值1地址(首地址),arr[2]和a指向同一位置,储存3的内存地址,所有这些都在栈内 A a = new A();
a 为 new A()的引用,同上在栈里新建一个a,new A()建在堆内,a指向它的首地址String比较特殊
String s1 = "abc"; //1
String s2 = "abc"; //2
String s3 = new String("abc"); //3
String s4 = new String("abc"); //4
假设以上代码按1、2、3、4顺序执行,执行1代码时,编译器先在栈内建立一个变量为s1的引用,再在栈内寻找有无存储数据为"abc"的内存单元,有则将s1指向该内存地址,执行到2时,因栈内已有内存单元值为"abc",此时直接将s2指向该内存单元,即s1、s2都指向同一内存。
执行到3时,同 A a = new A(),执行到4时再新建,过程同3
即:s1、s2、s3、s4都在栈内,在栈内有一内存值为"abc",s1、s2都指向该地址,s3、s4也在栈内,堆内有两处内存值为"abc",s3、s4分别指向它们。
PS:这些都可以用“==”测试出来。
谢谢六楼,这个是我最想要的答案,但是回答的真的全对么?我目前也无法完全相信。
因为七楼的回答被八楼否决,所以暂时没看。
Java虚拟机规范我刚才也看了些,比较深,有空再去读他,再此也谢谢八楼。现在我再总结下,大家看对么:
1.八大基本类型以及其数组类型的引用都是被创建在栈上的;
2.八大基本类型的值也是创建在栈上的;
3.八大基本类型的封装类的引用都是被创建在栈上的;
4.八大基本类型的封装类的对象是创建在堆上的;(比如Float a = new Float(2,0f)中的new后面的部分,此问题在博客中见到,但还是不确定)
5.String的引用及其值都是存储在栈上的;
6.new String("~~")是存储在堆上的。
2.基本类型的引用(例如int a;的那个“a”)是存储在“栈”上的; \\对
3.所有类的对象由new生成,并存储在“堆”上; \\对
4.所有的基本类型(例如int i = 3;的那个“3”)是存储在“栈”上的;\\对
5.Object obj[];中的引用“obj”是生成于“栈”上的; \\对
6.Object obj[] = new Object[10];中的“new Object[10]”是存储在“堆”上的; \\对
7.int i[];中的引用“i”是生成于“栈”上的; \\对
8.int i[] = new int[10];中的“new int[10];”是存储在“栈”上的; \\错,在堆上
9.标注static的类和变量被存放于特定的静态存储区(仍旧在RAM上); \\对
10.栈上开辟内存的速度比堆要快,堆上开辟内存的速度要比静态存储区快; \\对
11
String ss = " abc ";//ss:堆栈;" abc ":栈 \\ss在堆中,"abc"在数据区
ss = ss.trim();//"abc":栈 \\不确定
ss = ss + "abc"+123;\\这三行代码就建立了一个ss应用在栈上仅供参考
谢谢zhangXT和甩狙
大致明白了,改日再从基础开始细读。