请考虑以下代码:
class MyObject {...}
class MyClass
{
public void executeSomeFunc()
{
// do something
}
public static void main(String args[])
{
int x = 1;
x++; // where does GC starts on "x" ? after that line ?
int y = 2; // or after that ? or somewhere else
y++;
executeSomeFunc(); // declared earlier
// more code
// much more
MyObject myObj = new MyObject();
// more code
}
}
我对GC开始在x
上工作的位置感兴趣。
它在哪里?在x++;
之后?或者在代码中的另一个点?
编辑:
myObj
怎么样?
非常感谢
答案 0 :(得分:3)
答案是从不。 x
是基本类型的局部变量。它的值在堆栈上分配。一旦弹出堆栈帧(例如方法返回),就会立即取消分配内存,不涉及垃圾收集。
对于myObj
引用的对象,如果方法返回后没有引用链,则它有资格进行垃圾回收。
答案 1 :(得分:0)
垃圾收集器在未引用时收集对象。但是GC收集对象。 x和y是原始类型。因此,它们将会在那里直到主要运行。
对于myObject,GC不会做任何事情。如果在某个时刻为其指定null,则将收集该对象。
同样,不会收集原始类型。
答案 2 :(得分:0)
当本地引用超出范围/从堆栈帧中消失时,GC变为活动状态。这通常是在方法返回时。
GC规范是从活动线程开始将对象标记为“可到达”。堆栈帧。它遍历&标记所有可到达的对象,然后收集无法访问的对象。并行和并发收集器精确地改进了&当这种情况发生时,这是基本方法。
答案 3 :(得分:0)
GC运行的时间以及对象何时符合GC的条件是两个非常不同的问题。仅仅因为一个对象符合GC的条件并不意味着GC会立即运行以恢复它。
在您的示例中,x和y是基元,它们不是GC候选者。 GC主要应用于对象堆而不是基于堆栈的数据。正如Sotirios上面提到的,相信x是gc候选人是错误的。一旦定义它的范围结束并且假设myObj没有在该范围内泄露,myObj将成为GC候选者。
现在关于GC何时运行以回收myObj?答案就是,没有人知道。 GC实现主要基于守护程序线程(有时也在应用程序线程中),并且它们扫描堆中的垃圾。只有保证会发生的事情是,当app尝试为正在创建或重构的对象分配一些内存时,JVM会因为不可用而拒绝它(这在GC术语中称为分配失败事件),那么GC线程将被触发以回收任何记忆,如果可用。他们首先在伊甸园空间运行,以收回任何年轻的记忆,孤儿被清理,其他人被转移到幸存者的空间。他们GC在终身空间运行。同样的事情也发生在那里。一旦它被清除,幸存者物体就会移动点,并且GC会休眠。如果无法回收内存,则会出现OutOfMemory异常。如果记忆恢复了,你就不会感觉到什么,一切都像往常一样。