释放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;
这将重置字符串生成器并使它有资格进行垃圾回收吗?!
答案 0 :(得分:3)
简单:与
一起使用sb = null;
,剩下的就忘了。
为什么?一旦GC可以确定某个对象符合垃圾回收的条件,它也知道从该对象引用的所有事物均符合条件。考虑到您对GC踢入,清理对象和释放内存没有没有控制的事实,上述分配就足够了。
因为它可以清楚地传达您的意图,然后帮助GC开展工作。实际上,编写良好的代码甚至可能不需要该语句。
现在,也许这实际上还不够好。但是,然后我们将在非常定义和狭窄的环境中讨论一个真正的性能问题。在这种情况下,您无需依靠传闻便可以开始衡量。
换句话说:如果您没有真正的性能问题出现在您的设置中,并且需要采取措施,那么您将使用简单,清晰的代码,避免进行各种“源代码级”优化。但是,如果您遇到了实际的性能问题,则应相应地进行处理:确定根本原因,并可能通过测量在现实中如何解决不同的选择。
还有别的气味过早优化了!
答案 1 :(得分:3)
如果您确实希望尽快释放内存,则需要查看GC选项而不是代码。
为此目的对GC选项进行的详细分析超出了此处的合理范围-但具体而言,可以将新的Shenandoah GC调整为在释放内存方面比G1或并发标记更具攻击性。 / sweep,所以这可能是您想要使用的。您可以使用-XX:+UseShenandoahGC
进行指定。 (这是特定于OpenJDK的,目前仍处于试验阶段,但是如果您想要执行此操作,则可以这样做。)
要获得更快的发布时间,您可能希望为ShenandoahUncommitDelay
和ShenandoahGuaranteedGCInterval
使用较小的值。较小的值(广义上讲)将更频繁地,更积极地运行GC,因此使用更多的CPU周期-但这样做的效果是,与以前的GC版本相比,内存释放速度非常快。 / p>
如果您只是要确保释放内存,以便它有资格快速回收垃圾,那么您只需要确保对该StringBuilder
的所有引用都设置为null尽早的机会。即使在这种情况下,我还是鼓励您分析并检查是否需要显式地执行此操作-现在,在许多情况下,JVM足够聪明,可以将对象标记为有资格使用GC,即使它们在技术上仍在范围内(只要能看到它们就不再在该范围的其余部分被引用。)
答案 2 :(得分:2)
确保StringBuilder
可以进行垃圾回收的唯一安全方法是与所有对象相同:杀死所有对其的引用。这意味着将其显式设置为null
或使其超出范围。
除此之外,您无法控制何时释放内存。您最多可以做的是请求垃圾回收,这很少是个好主意(更不用说您只是在请求,而不是命令JVM进行垃圾回收)。
除非您深入研究了代码并确信完全刷新了对象的状态,否则不能保证您提出的其他选择会释放所有内存。因此,如果要确保所有内容都是“干净的”,通常只对整个对象引用为空,然后重新开始通常会好得多。
答案 3 :(得分:1)
只需让StringBuilder对象超出范围(在大括号内),不要用不必要的语句使代码混乱,以免使垃圾收集器更快地完成工作。当StringBuilder对象超出范围时,它将可以进行垃圾回收。保持源代码干净。
答案 4 :(得分:0)
可能的解决方案包括3个步骤:
sb.setLength(0)
。这会将字符串生成器的内部长度设置为0
,这是步骤2所需的。sb.trimToSize()
。这会将value
数组替换为新的修剪后的数组,在我们的示例中,大小为char[]
的{{1}} 0
将删除您对sb = null
的引用。如果字符串构建器仅由您使用,并且未在其他任何地方传递,则这应使先前的StringBuilder
数组和字符串构建器eglibe进行垃圾回收。
尽管何时实际发生还取决于JVM,所以“最快的方法”可能是不可能的,因为它实际上是随机的。