我想确认哪个场景会导致对象myObj上的垃圾收集:
场景1
ArrayList arList = new ArrayList();
while(someCondition)
{
myObj = new MyObect(); // a custom object
arList.add(myObj);
}场景2
ArrayList arList = new ArrayList();
while(someCondition)
{
myObj = new MyObect(); // a custom object
arList.add(myObj);
myObj=null;
}显式地将对象设置为null是否会改善垃圾收集行为,还是在使用新构造函数重置对象时会是相同的?
发布于 2010-01-20 06:08:15
您没有指定myObj的范围及其重要性。如果它是一个局部变量,那么它几乎肯定无关紧要。如果它是一个实例变量,那么这可能是一个长期存在和不必要的引用,在这种情况下,设置为null将是有用的。
更新:给出了更新后的信息,即myObj是该方法的本地信息,在循环每次迭代结束时将其设置为null是零值。考虑一下这个例子:
public void process(String text) {
String[] lines = text.split("\n");
List<MyObject> list = new ArrayList<MyObject>();
Object myObj;
for (String line : lines) {
myObj = new MyObject(line);
list.add(myObj);
// 1. set myObj = null here
}
list = null; // 2
// 3. do some other stuff
}
public class MyObject {
private final String line;
public MyObject(String line) {
this.line = line;
}
}在这个例子中,假设在第3步,它花费了很长的时间。说十分钟吧。在这10分钟内,myObj指向处理的最后一行。听起来不像是个问题?有可能是这样。在Java中,子字符串的工作方式是引用原始字符串。所以如果你这么做了:
String s = ... // 100 megabytes
String s2 = s.substring(100, 101);实际上,您将整个100 s2保存在内存中,因为s2引用了s。
因此,在我前面的函数中,myObj引用了一行引用整个文件的行。将步骤1更改为myObj = null;实际上会有所帮助,因为此引用将防止垃圾收集对象。
注意:步骤2在这里很重要,因为如果您不取消列表,那么所有引用都会存在。
你只需要考虑一下引用是如何工作的。当对对象的引用存在时,它不会被垃圾收集。这意味着清除长期存在的引用并尽可能严格地保持变量的作用域。解决上述问题的正确办法是:
for (String line : lines) {
Object myObj = new MyObject(line);
...
}然后,myObj在循环中被限定范围,所以当循环结束或另一个迭代开始时,它已经超出了范围,这要好得多。
发布于 2010-01-20 06:07:11
将其设置为null不会有任何效果,因为通过arList对象仍然是可达。
也就是说,您的MyObect实例将至少与arList一样长。
编辑:根据您的评论,myObj听起来确实更长寿。在这种情况下,在循环结束后将其设置为null。
发布于 2010-01-20 06:29:21
我认为这是你误解的根源。
嗯..。但我不希望保留两个myObj副本,一个在arList中,一个在原始变量中。一旦我将myObj添加到arLsit中,如何冲洗它?
你不能“保留两份myObj”。在您的示例中,循环创建的每个MyObject实例只有一个“副本”。顺序如下:
myObj。arList引用的arList。null分配给myObj中的引用。请注意,将引用添加到列表并不会创建MyObject实例的副本。它仅仅意味着你在两个地方而不是一个地方有引用。当您分配null时,您将再次将引用放在一个位置上。
另外要注意的是,将null分配给某物永远不会导致垃圾收集器运行。它所做的就是(显式地)在下次运行垃圾收集器时从考虑中删除引用的潜在副本。
最后,如果我们假设范围如下,则C行将没有明显的效果.除非A行或B行触发垃圾回收。
{
MyObject myObj;
ArrayList arList = new ArrayList();
while (someCondition) { // A
myObj = new MyObect(); // B
arList.add(myObj);
myObj = null; // C
}
}https://stackoverflow.com/questions/2099354
复制相似问题