【问题标题】:Object life cycle in java and memory management?java中的对象生命周期和内存管理?
【发布时间】:2013-08-08 10:42:17
【问题描述】:

对于程序中的以下语句,在堆内存和字符串常量池中将创建多少个对象?

我需要清楚地创建对象。我读过的许多资料都没有详细说明。当对象被破坏时我很困惑。

String a="MAM"+"BCD"+"EFG"+"GFE";

将创建多少个对象?

我正在寻找有关对象、方法和类的生命周期以及 JVM 在动态更改和修改它们时如何处理它们的好材料。

【问题讨论】:

  • 有人应该在上面运行javah。我敢打赌它只会显示一个常数。
  • 在这个讨论中只有我一个但很多朋友让我很困惑link

标签: java string object heap-memory


【解决方案1】:

只创建一个对象。

string s1 = "java";
string s2 = "ja" + "va";
s.o.p(s1==s2);

该语句的结果为真。

String s1="java";
string s2 = "ja";
String s3 = s2 +"va";
s.o.p(s1==s3);

该语句产生错误。

所以至少一个明显的应该是永久的,然后'+'运算符生成新的字符串对象(在非常量池中使用 new())。 所以,你问的问题也不是永久的。这意味着它只创建一个对象。

【讨论】:

    【解决方案2】:

    只创建一个对象并将其放置在常量池中,除非它已经存在,在这种情况下使用现有对象。编译器将字符串常量连接在一起,如 JLS 3.10.5 和 15.28 中所指定。

    一个长字符串总是可以被分解成更短的部分,并使用字符串连接运算符 + 写成一个(可能带括号的)表达式

    http://docs.oracle.com/javase/specs/jls/se7/html/jls-3.html#jls-3.10.5

    【讨论】:

      【解决方案3】:

      "MAM"+"BCD"+"EFG"+"GFE" 是一个编译时常量表达式,它编译成"MAMBCDEFGGFE" 字符串文字。当加载包含上述代码的类时,JVM 会从这个字面量创建一个String 的实例,并将这个String 放入字符串池中。因此String a = "MAM"+"BCD"+"EFG"+"GFE"; 不会创建任何对象,请参阅 JLS 15.18.1. String Concatenation Operator +

      String 对象是新创建的(第 12.5 节),除非表达式是编译时常量表达式(第 15.28 节)。

      它只是将池中String 对象的引用分配给本地变量a

      【讨论】:

        【解决方案4】:

        将只创建一个对象,因为String a 将编译为"MAMBCDEFGGFE"

        【讨论】:

          【解决方案5】:

          在您的示例中说明单个堆对象的答案是正确的。但是,请考虑以下代码:

          public class Tester
          {
             public String a="MAM";
             public String b ="BCD";
             public String c = "EFG";
             public String d ="GFE";
          
             public Tester()
             {
                String abcd = a + b + c + d;
             }
          }
          

          在本例中,创建了 7 个字符串。 a,b,c 和 d 不会编译成单个常量 - 它们是成员。然后为每个 + 运算符创建一个字符串 - 从语义上讲,+ 是一个串联,但从逻辑上讲,它是在内存中创建一个新字符串。前 2 个运算符字符串会立即被丢弃,现在可以进行垃圾回收,但仍然会发生内存流失。

          从技术上讲,在第 8 个对象中。 Tester 的实例。

          编辑:这在 cmets 中已被证明是无稽之谈

          【讨论】:

          • javac 编译器有一个优化:不是每个+ 都会生成一个新字符串。插入一个内部StringBuilder,添加abcc,然后创建一个String。这种优化已经存在了十多年。所以计算是 5 个String 和 5 个关联的char[],1 个StringBuilder 加上至少一个关联的char[] - 由于动态调整大小,最终更多。
          • 你的意思是它会先附加 a+b 然后将 a+b 视为一个字符串并附加到 c ??我没有得到你
          【解决方案6】:

          大多数答案似乎都集中在 a) 完整的表达式是 one 编译时间常数和 b) 该行本身不构造新对象,而只是对 one 的引用em> 对象。

          然而到目前为止没有人提到,String 本身包含对内部char[] 的引用(它也在常量池中)。

          总结:常量池中有两个对象(Stringchar[])。该行既不创建也不销毁任何对象。

          关于:

          当对象被破坏时我很困惑。

          没有对象被销毁,因为常量池中的东西只有在类本身被卸载时才会被销毁。最多可以说,引用 a 最终会超出范围。

          【讨论】:

            猜你喜欢
            • 1970-01-01
            • 2012-10-14
            • 1970-01-01
            • 2012-11-06
            • 2020-07-28
            • 1970-01-01
            • 2012-12-17
            • 2011-06-27
            • 2012-12-28
            相关资源
            最近更新 更多