Java input =“”与input = null不同?

时间:2009-07-24 18:27:12

标签: java memory-management java-me garbage-collection

我正在运行J2ME应用程序并遇到一些严重的内存问题 所以我构建了另一个步骤来清除巨大的输入字符串并处理其数据并清除它。 但在我设置 input = null 而不是 input = "" 之前,它无法解决问题。

在内存管理方面不应该是一样的吗?有人可以解释一下我的区别吗?

谢谢,
rAyt

for(int x = 0; x <= ChunksPartCount; x++)
{
    _model.setLoading_bar_progress((x * ChunkSize));
    input += web_service.FullCompanyListChunksGet(x, ChunkSize);

    if((x * ChunkSize) > 5000)
    {
        ReadXML(input);
        input = null;
    }
}

修改
我仍然希望将答案标记为解决方案。我认为mmyers的言论正朝着正确的方向发展。

6 个答案:

答案 0 :(得分:11)

每个变量实际上都是指向内存中“数据”的指针。

input =“”将输入分配给字符串对象。它有一个长度(0)和一个空数组,以及与之相关的一些其他数据。

input.length()此时将返回0。

input = null使输入指向“无效”。 Null是一种特殊情况,意味着这个指针指向NOTHING,它是未分配的。

input.length()现在会抛出一个异常,因为你什么都不调用.length。

答案 1 :(得分:5)

input = null删除(让Garbage收集器删除)内存中的对象,而input = ""实例化包含空字符串String的{​​{1}}对象。通过将输入设置为null,您将""设置为空对象,因此它不会占用任何内存,而在设置input =“”时,您将其设置为新对象,这肯定会占用一些内存(显然它应该是最小的)。

您可以从input查看this article,讨论Java GC和性能,这会阻碍我之前的建议。它说:

  

显式归零就是这样   设置参考对象的做法   完成后为null   他们。 归零的想法是   它协助垃圾收集器   使对象更早无法访问要么   至少那是理论。

     

有一种情况使用   显式归零不仅有用,   但实际上是必需的,那就是   其中对象的引用是   比使用或更广泛的范围   被程序视为有效   规范。这包括案例   例如使用静态或实例   用于存储对a的引用的字段   临时缓冲区,而不是本地缓冲区   变量,或使用数组来存储   可能仍然可以访问的引用   由运行时但不是由隐含的   程序的语义。

此外,

  

在1997年9月的“Java开发人员连接技术提示”专栏(请参阅参考资料)中,Sun警告了这种风险,并解释了在上面的pop()示例中如何需要显式的归零。不幸的是,程序员经常采用这种建议太过分,使用显式归零来帮助垃圾收集器。 但在大多数情况下,它对垃圾收集器没有任何帮助,在某些情况下,它实际上伤害你的程序的性能。

答案 2 :(得分:5)

使用StringBuffer可能是更好的方法

其中一些已在SO中得到解答:

String builder and stringbuffer in java

why to use StringBuffer in java instead of the string concantion operator

答案 3 :(得分:3)

我没有猜测垃圾收集器为什么不收集你的对象,而是倾向于收集有关情况的证据。其他人已经发布了他们的猜测。

如果可能,创建堆转储文件以在运行代码时观察JVM中的内存,然后检查它们以查看那些对象。

这是一个网页,告诉您如何做到这一点: http://twit88.com/blog/2008/12/19/java-troubleshooting-memory-problem/

祝你好运!


另一个想法:编写一个简短的程序,除了创建大型的String对象,然后打开详细的垃圾收集模式,看看那里发生了什么。如果您可以在小程序中重现行为,那么您可以更轻松地学习它。我想您可能会发现PC上的JVM可能与J2ME设备(如手机)中的JVM行为不同。

答案 4 :(得分:2)

我想在旅行者的回答中加一点:

关于字符串

垃圾收集立场中的语句input = "";与编写input = "abcde...";相同,因为这两个语句都无法使对象实例input无效,但两者都只是更改{{1}的内容1}}变量。此外,为了精确和澄清,input String更改input = something"的内容,而input实例化String input = "";

如果输入==“”,那么'if(input.isEmpty())input if(input == null)`将为false。

关于垃圾收集

语句would be true, but递减此特定对象实例的引用计数,如果它是input = null;的最后一个引用,那么input将被标记为垃圾收集,这将发生当垃圾收集器到达它时,非确定性的AKA。 input实际上不会标记input = null;垃圾收集的情况是:如果input也被传递到集合中;直到input从集合中删除,它将使引用计数不再减少,因此不会被垃圾收集。

希望这有助于其他任何人,请随时纠正任何错误,即使它们很微妙。

-bn

答案 5 :(得分:1)

在Java字符串中,对象和对象变量名称始终是指针。如果您有一个名为input的String并输入input = null,则将输入指向内存中的空白空间。如果你有input =“”,它会创建一个不包含文本的字符串,一个空字符串。