释放stringbuilder内存的最快方法

时间:2019-01-17 11:58:29

标签: java performance garbage-collection

释放stringbuilder内存的最快方法是什么。

 StringBUilder sb = new StringBuilder();
 sb.apppend(maximum value possible);

下面是我试图尽快释放内存并使对象有资格进行垃圾回收的代码段

选项1:

sb = null;

根据我的理解,stringbuilder中的所有数据将被删除,并且对象一旦被踢入,就可以进行垃圾回收,但是stringbuilder占用的文本内存将被释放。还会将其中的字符串值从堆中删除还是存储在字符串池中?

选项2:

 sb.setLength(0);

这将重置字符串生成器的长度,但不会被垃圾收集

选项3:

 sb.delete(0,sb.length());

这将通过删除字符串生成器中的所有数据来重置字符串生成器,但不会对其进行垃圾收集

选项4:

 sb.delete(0,sb.length());
 sb = null;

这将重置字符串生成器并使它有资格进行垃圾回收吗?!

5 个答案:

答案 0 :(得分:3)

简单:与

一起使用
sb = null;

,剩下的就忘了。

为什么?一旦GC可以确定某个对象符合垃圾回收的条件,它也知道从该对象引用的所有事物均符合条件。考虑到您对GC踢入,清理对象和释放内存没有没有控制的事实,上述分配就足够了。

因为它可以清楚地传达您的意图,然后帮助GC开展工作。实际上,编写良好的代码甚至可能不需要该语句。

现在,也许这实际上还不够好。但是,然后我们将在非常定义和狭窄的环境中讨论一个真正的性能问题。在这种情况下,您无需依靠传闻便可以开始衡量。

换句话说:如果您没有真正的性能问题出现在您的设置中,并且需要采取措施,那么您将使用简单,清晰的代码,避免进行各种“源代码级”优化。但是,如果您遇到了实际的性能问题,则应相应地进行处理:确定根本原因,并可能通过测量在现实中如何解决不同的选择。

还有别的气味过早优化了!

答案 1 :(得分:3)

如果您确实希望尽快释放内存,则需要查看GC选项而不是代码。

为此目的对GC选项进行的详细分析超出了此处的合理范围-但具体而言,可以将新的Shenandoah GC调整为在释放内存方面比G1或并发标记更具攻击性。 / sweep,所以这可能是您想要使用的。您可以使用-XX:+UseShenandoahGC进行指定。 (这是特定于OpenJDK的,目前仍处于试验阶段,但是如果您想要执行此操作,则可以这样做。)

要获得更快的发布时间,您可能希望为ShenandoahUncommitDelayShenandoahGuaranteedGCInterval使用较小的值。较小的值(广义上讲)将更频繁地,更积极地运行GC,因此使用更多的CPU周期-但这样做的效果是,与以前的GC版本相比,内存释放速度非常快。 / p>

如果您只是要确保释放内存,以便它有资格快速回收垃圾,那么您只需要确保对该StringBuilder的所有引用都设置为null尽早的机会。即使在这种情况下,我还是鼓励您分析并检查是否需要显式地执行此操作-现在,在许多情况下,JVM足够聪明,可以将对象标记为有资格使用GC,即使它们在技术上仍在范围内(只要能看到它们就不再在该范围的其余部分被引用。)

答案 2 :(得分:2)

确保StringBuilder可以进行垃圾回收的唯一安全方法是与所有对象相同:杀死所有对其的引用。这意味着将其显式设置为null或使其超出范围。

除此之外,您无法控制何时释放内存。您最多可以做的是请求垃圾回收,这很少是个好主意(更不用说您只是在请求,而不是命令JVM进行垃圾回收)。

除非您深入研究了代码并确信完全刷新了对象的状态,否则不能保证您提出的其他选择会释放所有内存。因此,如果要确保所有内容都是“干净的”,通常只对整个对象引用为空,然后重新开始通常会好得多。

答案 3 :(得分:1)

只需让StringBuilder对象超出范围(在大括号内),不要用不必要的语句使代码混乱,以免使垃圾收集器更快地完成工作。当StringBuilder对象超出范围时,它将可以进行垃圾回收。保持源代码干净。

答案 4 :(得分:0)

可能的解决方案包括3个步骤:

  1. 致电sb.setLength(0)。这会将字符串生成器的内部长度设置为0,这是步骤2所需的。
  2. 致电sb.trimToSize()。这会将value数组替换为新的修剪后的数组,在我们的示例中,大小为char[]的{​​{1}}
  3. 0将删除您对sb = null的引用。

如果字符串构建器仅由您使用,并且未在其他任何地方传递,则这应使先前的StringBuilder数组和字符串构建器eglibe进行垃圾回收。

尽管何时实际发生还取决于JVM,所以“最快的方法”可能是不可能的,因为它实际上是随机的。