请有人澄清一下下面的情况,以便更好地掌握java内存的分配和管理。谢谢。
Q1)以下三个代码片段之间的差异是什么:为什么存在三个不同的代码片段?(内存分配的时间)
Fragment1:
Class C
{
StringBuffer sb = new StringBuffer();
C(){}
}
Fragment2:
Class C
{
StringBuffer sb;
C()
{
sb = new StringBuffer();
}
}
Fragment3:
Class C
{
C()
{
StringBuffer sb = new StringBuffer();
}
}
Q2)如何维护在没有引用变量的情况下创建的对象。例如,新C(); 新C().Hello();如何理解它们的内存管理、默认值、范围!!
( Q3)以下两个片段之间的差异:
Fragment1
Class C
{
int a;
C(){}
}
Fragment2
Class C
{
C(){int a;}
}
发布于 2014-02-12 03:19:53
Q1)片段1和片段2是等价的。如果类C
有多个构造函数,则会有不同。在片段1变体中,您只编写一次初始化,而在片段2变体中,您需要在每个构造函数中编写它。
在片段3中,变量sb
是构造函数中的局部变量,仅在那里可见。当构造函数结束时,可以垃圾收集StringBuffer
对象。
Q2)它将不会被维护,创建后它可以立即被垃圾收集。在new C().Hello();
的情况下,只有在Hello()
方法退出之前才能保证对象的存在。
Q3)片段1声明类字段,片段2在构造函数中声明局部变量。
发布于 2014-02-12 04:15:36
对其他答案的补充:
如果创建了一个新对象,JVM将始终在运行程序的堆中分配内存,并将该对象放置在那里。在所有示例片段中,生成的StringBuffer
对象将被放置在堆中。
使用new
关键字创建新对象还会返回对该对象的引用。可以将此引用赋值给变量。下面是例子片段的不同之处。在片段1和2中,您将此引用分配给实例变量(又名字段),它是对象数据的一部分--这里是类C
的实例。因此,这些实例变量也驻留在堆中。只要有对C
实例的引用(可能在主方法中),就一定会有对包含的StringBuffer
实例的引用。
在片段3中,将此引用赋值给局部变量。局部变量的内存分配在堆栈上,而不是堆上。当方法结束时,此内存分配也将被丢弃。不再存在(局部变量),它可以保存对对象的引用。
如果不再有对对象的引用,则认为对象有资格进行垃圾收集。在您的片段3中,构造函数结束后,StringBuffer
实例将是这样的。注意,Java垃圾收集器不会立即运行和删除所有垃圾。它将在JVM选择的适当时间运行。
https://stackoverflow.com/questions/21726240
复制