嗨,我试图发现为什么我的程序通常比我想要的慢,所以先谢谢你的帮助!
我有一段代码,我想深入了解一下
1. while(conditionIsTrue){ 2. Object object = new Object(); 3. }
在第2行.我创建了一个新的Object.这将在我的程序中发生数千次.在gc销毁它之前,我是否必须将旧的Object清零?或者gc会在我的程序后面获取其他对象使用的所有内存.
或者另一种选择是这种情况发生:正在分配一定量的内存,每次创建一个新的Object时,它都被分配给完全相同的内存.
布鲁诺让我展示一个更现实的代码片段,这样我们就可以找出它运行缓慢的原因.但是,由于你的答案Bruno我意识到我的代码是这样的
1. Object object = null; 2. while(conditionIsTrue){ 3. object = new Object(); 4. }
所以我意识到我对我的对象有强烈的引用.谢谢布鲁诺!
解决方法
在这种情况下,您不需要object = null;允许GC清除新的Object(),因为在实例化对象完成的迭代之后没有任何引用留给对象(即第3行).
规则是:只要没有指向它的strong references,就允许GC清除对象.它可能不会立即清除对象,可能需要一些时间,但除非你设法获得新的强引用(是的,有方法!例如参见SoftReference
和WeakReference
),它最终将被清除,当然在之前它抛出一个OutOfMemoryError
.
此外,JVM在分配内存方面非常聪明.有一个叫做escape analysis的东西:它允许JVM理解新的Object()不会在该循环之外的任何地方使用,因此它甚至可以在堆栈上而不是在堆上为对象分配内存!因此,对于该特定对象可能根本不需要GC – 当方法完成时,对象将自动清除.
我甚至会猜测JVM可能会检测到实例化该对象根本没有明显的效果,甚至可能只是选择不运行那条#2行(但这是一个猜测,如果我可以考虑进行优化正在编写一个编译器 – 如果有人确切知道这是否发生,请添加评论!).
如果您的程序运行速度比运行速度慢,那么您必须显示一些更实际的代码.您可能会认为您的实际代码与您询问的代码段之间的细微差别可能是JVM的巨大差异!