首页
学习
活动
专区
圈层
工具
发布
社区首页 >问答首页 >java中的字符串文字和垃圾收集器

java中的字符串文字和垃圾收集器
EN

Stack Overflow用户
提问于 2014-05-29 20:58:10
回答 2查看 618关注 0票数 1

更具体地说,我在java7中读到,字符串文字现在存储在堆的主要部分中,那么,它们是否有资格成为垃圾收集器?

代码语言:javascript
复制
String a ="z";
a = null;

现在,对象"z“是得到垃圾回收,还是仍然作为匿名对象留在字符串池中?

EN

回答 2

Stack Overflow用户

发布于 2014-05-29 21:22:56

字符串文字只有在包含这些文字的所有类都为GCed时才能为GCed,而只有在装入这些类的ClassLoaders为GCed时才会发生这种情况。

示例:

代码语言:javascript
复制
public interface I {
    String getString();
}

public class Test2 implements I {
    String s = "X";
    @Override
    public String getString() {
        return s;
    }
}

public class Test implements I {
    String s = "X";
    @Override
    public String getString() {
        return s;
    }
}

public class Test1 {

    public static void main(String[] args) throws Exception {
        ClassLoader cl = new URLClassLoader(new URL[] {new URL("file:d:/test/")});
        I i = (I)cl.loadClass("Test").newInstance();
        WeakReference w = new WeakReference(i.getString()); //weak ref to "X" literal
        i = null;
        cl = null;
        System.out.println(w.get());
        System.gc();
        Thread.sleep(1000);
        System.out.println(w.get());
    }
}

编译这些类,将测试移动到d:/ Test.class,这样系统类装入器就看不到它了,然后运行main。你会看到

代码语言:javascript
复制
X
null

这意味着"X“是GC编辑的

票数 1
EN

Stack Overflow用户

发布于 2014-05-29 21:11:39

  • 等效的字符串文字(甚至那些存储在不同包中的不同类中的字符串文字)将引用相同的字符串对象。
  • 一般来说,字符串文字不符合垃圾回收的条件。在运行时创建的字符串将始终与通过字符串文字创建的字符串不同。
  • 您可以通过使用Ever.
  • Strings ()方法将字符串文字与运行时字符串一起重用。
  • 检查字符串相等的最佳方法是使用
  • ()方法。

来源:

http://www.javaranch.com/journal/200409/ScjpTipLine-StringsLiterally.html

请注意,这有点高级-您必须了解类String的内部工作原理才能理解这一点。

字符串对象将其数据存储在字符数组中。通过调用substring()方法获取字符串的子字符串时,创建的新string对象不会复制原始字符串的部分数据。相反,它存储对原始字符串的基础数据的引用,以及偏移量和长度,以指示新字符串对象表示的旧字符串的哪一部分。

当您有一个非常长的字符串(例如,您将一个文件的内容读取到一个string对象中)并从中取出一个子字符串时,JVM将在内存中保留原始字符串的所有数据-即使您丢弃了原始String对象,因为使用substring()创建的string对象仍然包含对包含所有数据的整个字符数组的引用。

为了防止这种内存效率低下,您可以使用substring对象显式创建一个新的String对象。第二个新的String对象将从substring对象复制数据,但这正是您需要的部分。查看普通打印?注意:代码块中的文本内容会自动换行

代码语言:javascript
复制
// Suppose this contains 100K characters read from a file  
String largeString = ...;  

// This will refer to the 100K char array from largeString, keeping the whole buffer in memory  
// even though sub represents only 20 characters  
String sub = largeString.substring(80, 100);  

// This will copy the 20 characters from sub into a new buffer, so that the whole 100K buffer doesn't need to be kept  
String sub2 = new String(sub);  

如果您想了解它到底是如何工作的,那么可以查看String类的源代码,您可以在JDK安装目录中的src.zip文件中找到它。

来源:

http://www.coderanch.com/t/542489/java/java/string-literal-String-Object

票数 0
EN
页面原文内容由Stack Overflow提供。腾讯云小微IT领域专用引擎提供翻译支持
原文链接:

https://stackoverflow.com/questions/23933912

复制
相关文章

相似问题

领券
问题归档专栏文章快讯文章归档关键词归档开发者手册归档开发者手册 Section 归档