【问题标题】:Java HeapDump Analysis: String or StringBuilder, what should be used?Java HeapDump分析:String还是StringBuilder,应该用什么?
【发布时间】:2016-09-16 02:17:06
【问题描述】:

在我的应用程序中有一个堆转储,令人惊讶的是char[] 保留的堆大约是 700MB,这很奇怪(至少对我来说)。同时String只有150MB。

在我的应用程序中,我只使用了StringBuilder(使用默认的StringBuilder 构造函数)并尽量避免使用String,因为我们正在附加数据。

我的问题是:我们是否应该一直选择StringBuilder?如果是,我们如何减少它保留的堆?

【问题讨论】:

  • 如果你总是使用StringBuilder的默认构造函数,它可能需要在你填充它们时继续在内部分配更大的char[]实例(大约需要两次空间就好像预先知道最终的大小一样)。但可能更重要的是,当你构建最终的String 时,StringBuilder 中的char[] 必须被复制。
  • 您可能希望在完成附加后从StringBuilder 中取出已完成的String,然后将StringBuilder 扔掉。
  • @Andy Turner:我们将所有 String 变量声明为 final,因为它们都是局部变量。
  • @SauravKumarMehta:如果这是占用空间大的原因,那么我不会担心,因为内存实际上是“可用的”(即使它仍在物理内存中),因为它可以在必要时进行垃圾收集。

标签: java string stringbuilder heap-memory


【解决方案1】:

是的,在构建字符串时总是选择StringBuilder - 这是最有效但仍然方便的连接字符串的方式。

听起来好像有很多StringBuilders 在等待垃圾收集。但是,为了减少堆使用,您可以安全地重用您的 StringBuilders,即使它们不是线程安全的,也可以通过 Threadlocal 每个线程使用一个 StringBuilder:

private static final ThreadLocal<StringBuilder> LOCAL_STRING_BUILDER =
    ThreadLocal.withInitial(StringBuilder::new);

示例用法:

public String logMessage() {
    StringBuilder sb = LOCAL_STRING_BUILDER.get();
    sb.setLength(0); // Only resets the pointer to start. Doesn't affect the backing array
    sb.append("foo=").append(myField); //etc
    return sb.toString();
}

您最多只能拥有与线程一样多的StringBuilders,而线程数不会那么多(可能是 10 到 100 个)。


FYI StringBuilder 无论如何都在手动连接字符串时使用;这行来源:

String str3 = str1 + str2;

被编译为:

String str3 = new StringBuilder().append(str1).append(str2).toString();

【讨论】:

    【解决方案2】:

    您可能可以使用 StringInterner ,它采用 StringBuilder 来避免不必要地创建对象。您首先使用文本填充回收的 StringBuilder ,如果与该文本匹配的字符串在内部,则返回该字符串(或 toString() StringBuilder 是。)好处是,当您看到一个新字符串(或至少一个不在数组中)时,您只创建对象(并且不超过需要)这可以获得 80% 到 99% 的命中率并减少内存加载许多数据字符串时会显着消耗(和垃圾)。

    代码: https://github.com/OpenHFT/Java-Lang/blob/master/lang/src/main/java/net/openhft/lang/pool/StringInterner.java

    【讨论】:

    猜你喜欢
    • 2014-10-06
    • 1970-01-01
    • 2012-08-19
    • 2015-09-10
    • 2015-02-14
    • 2020-07-05
    • 1970-01-01
    • 1970-01-01
    • 2011-03-20
    相关资源
    最近更新 更多