【问题标题】:Garbage collection and Strings垃圾收集和字符串
【发布时间】:2010-02-04 18:30:05
【问题描述】:

我对字符串有一些疑问

它们是生活在堆还是字符串池上?

如果在堆上,如果任何活动线程都无法访问它们,那么它们将被垃圾回收。

如果在字符串池中,那么它们将如何被删除或移除,因为我们知道垃圾收集只发生在堆上。

【问题讨论】:

    标签: java


    【解决方案1】:
    String s = new String("abc");
    

    s 引用的字符串对象将在堆上,而字符串字面量“abc”将在字符串池中。字符串池中的对象不会被垃圾回收。它们可以在程序的生命周期内重复使用,以提高性能。

    【讨论】:

    • 如果您指的是作为类定义一部分的常量池,那么您可以卸载常量池,前提是您可以卸载类(通常需要取消引用类加载器以及对其加载的类的所有引用)。比你的典型程序更难,但 Tomcat 做到了。
    【解决方案2】:

    它们都存储在堆中,但intern()ed 字符串(包括源中的字符串文字)是从String 类的池中引用 .

    如果它们在源代码中以文字形式出现,包括常量字符串表达式(例如 "a" + "b"),那么它们也将被 Class 引用,这通常意味着只要进程运行它们就会持续存在.

    编辑: 当您在代码中对字符串调用 intern() 时,它也会添加到此池中,但由于它使用弱引用,因此如果不再使用该字符串可以仍然被垃圾回收。

    另请参阅: interned Strings : Java Glossary

    引用那篇文章:

    在这个 HashMap 中注册的字符串集合有时被称为字符串池。但是,它们是普通的对象,并且像其他任何对象一样都存在于堆上(也许以一种优化的方式,因为实习字符串往往寿命很长)。

    【讨论】:

      【解决方案3】:

      String Alex 进入字面量池,只要进程运行(或 Web 应用程序保持加载状态)就一直呆在那里。正如 finnw 所说,绝不是垃圾集。字符串 name2 不为“Alex”分配内存,而是从文字池中重用它。

      PS:文字池也在堆上。

      对于字符串 John,使用引用 name3 和 name4 创建了两个对象,它们是可垃圾回收的。

      String name = "Alex";
      String name2 = "Alex";
      
      String name3 = new String("John");
      String name4 = new String("John");
      

      【讨论】:

        猜你喜欢
        • 2013-05-30
        • 2013-02-25
        • 2013-02-15
        • 1970-01-01
        • 1970-01-01
        • 1970-01-01
        • 2013-02-17
        • 1970-01-01
        • 1970-01-01
        相关资源
        最近更新 更多