在方法内部创建的实例
Instance created inside of a Method
我没能找到任何关于此的可靠文献,但我很好奇如果对象是在方法内部创建的,它存储在哪里?在 java 8 中在堆栈上还是在堆上?
public class A {}
.
.
.
public class B {
public void test(){
A m = new A();
}
}
我知道通常只有局部基元、引用变量和函数调用存储在堆栈中,而对象存储在堆中
所以我假设以下两种情况之一为真
- 案例 1: 在方法中实例化的对象像往常一样存储在堆中,并引用堆栈中的该对象,然后当函数完成时,对象引用消失范围和堆中的对象然后可用于垃圾收集
- 情况 2: 在方法中实例化的对象存储在堆栈中,然后在函数完成时可用于垃圾回收
我强烈怀疑它的情况 1,将对象存储在堆栈中没有意义,我怀疑的唯一原因是因为我遇到过一些关于堆栈和堆上的文献
感谢您提前反馈
局部引用变量在栈中,object在堆中。
注意你的问题标题,
Instance declared inside of a Method
具有误导性,因为 objects/instances 被声明为 无处 -- 只有变量,并且创建了 object在一个方法中可以放置在 collection 中的字段上或任何需要的地方。因此无法保证 object 应该 在方法退出时被 GC。
所有对象都存储在堆中...只要内存不足,垃圾收集器就会运行,因此它会清除不再使用的对象,也没有对它们的引用。
您在案例 1 中指定的假设是正确的。这是 java.
中内存分配的一个很好的来源
如果它们不是立即数 "values"(不像 class 对象中的 int 属性),只有它们的引用值存储在堆栈中。它们的实际值和结构存储在堆中。
这些按原样存储在堆栈中;
int i=10;
float f=10.00;
bool b=true;
这些将只有堆栈上的引用,它们将驻留在堆中(任何类型的 class 变量都是结构的一部分,并且完全在堆上创建);
int[] ii={1,2,3};
double[] dd = new double[10];
String s="String!!";
Object o=new Object();
当传递给方法时,值被复制到新的堆栈变量(除非转换为引用对象)。引用也被传递给一个模仿堆栈变量,但由于它们是引用,它们将重定向到同一个对象(除非手动复制到一个全新的对象)。
这部分可能不是主题感兴趣的,你决定
在下面的代码中,数字在堆栈上创建并复制到方法的新堆栈值,hello 在堆上创建,通过引用传递给 s,然后两个字符串连接在另一个堆地址上,现在它持有这个新地址(字符串是不可变的)。 Point 对象不像字符串那样是不可变的,因此它可以在您引用它的任何地方更改,因为它们是在堆上创建的,可以自由访问。
class Point{ int x;int y; Point(int x,int y){this.x=x;this.y=y;} }
public class TestClass{
public static void main(String []args){
int number=5;
String hello="Hello";
Point point = new Point(2,4);
Print(number,hello,point);
System.out.println(hello+" "+number+" "+point.x+" "+point.y);
}
public static void Print(int i,String s,Point p){
i+=5;
s+="World!";
p.x+=2; p.y+=2;
System.out.println(s+" "+i+" "+p.x+" "+p.y);
}
}
我没能找到任何关于此的可靠文献,但我很好奇如果对象是在方法内部创建的,它存储在哪里?在 java 8 中在堆栈上还是在堆上?
public class A {}
.
.
.
public class B {
public void test(){
A m = new A();
}
}
我知道通常只有局部基元、引用变量和函数调用存储在堆栈中,而对象存储在堆中
所以我假设以下两种情况之一为真
- 案例 1: 在方法中实例化的对象像往常一样存储在堆中,并引用堆栈中的该对象,然后当函数完成时,对象引用消失范围和堆中的对象然后可用于垃圾收集
- 情况 2: 在方法中实例化的对象存储在堆栈中,然后在函数完成时可用于垃圾回收
我强烈怀疑它的情况 1,将对象存储在堆栈中没有意义,我怀疑的唯一原因是因为我遇到过一些关于堆栈和堆上的文献
感谢您提前反馈
局部引用变量在栈中,object在堆中。
注意你的问题标题,
Instance declared inside of a Method
具有误导性,因为 objects/instances 被声明为 无处 -- 只有变量,并且创建了 object在一个方法中可以放置在 collection 中的字段上或任何需要的地方。因此无法保证 object 应该 在方法退出时被 GC。
所有对象都存储在堆中...只要内存不足,垃圾收集器就会运行,因此它会清除不再使用的对象,也没有对它们的引用。
您在案例 1 中指定的假设是正确的。这是 java.
中内存分配的一个很好的来源如果它们不是立即数 "values"(不像 class 对象中的 int 属性),只有它们的引用值存储在堆栈中。它们的实际值和结构存储在堆中。
这些按原样存储在堆栈中;
int i=10;
float f=10.00;
bool b=true;
这些将只有堆栈上的引用,它们将驻留在堆中(任何类型的 class 变量都是结构的一部分,并且完全在堆上创建);
int[] ii={1,2,3};
double[] dd = new double[10];
String s="String!!";
Object o=new Object();
当传递给方法时,值被复制到新的堆栈变量(除非转换为引用对象)。引用也被传递给一个模仿堆栈变量,但由于它们是引用,它们将重定向到同一个对象(除非手动复制到一个全新的对象)。
这部分可能不是主题感兴趣的,你决定
在下面的代码中,数字在堆栈上创建并复制到方法的新堆栈值,hello 在堆上创建,通过引用传递给 s,然后两个字符串连接在另一个堆地址上,现在它持有这个新地址(字符串是不可变的)。 Point 对象不像字符串那样是不可变的,因此它可以在您引用它的任何地方更改,因为它们是在堆上创建的,可以自由访问。
class Point{ int x;int y; Point(int x,int y){this.x=x;this.y=y;} }
public class TestClass{
public static void main(String []args){
int number=5;
String hello="Hello";
Point point = new Point(2,4);
Print(number,hello,point);
System.out.println(hello+" "+number+" "+point.x+" "+point.y);
}
public static void Print(int i,String s,Point p){
i+=5;
s+="World!";
p.x+=2; p.y+=2;
System.out.println(s+" "+i+" "+p.x+" "+p.y);
}
}