q(旁白 - 我不确定创建但未存储在变量中的对象的术语是什么)。
我真的不知道如何很好地表达我的问题,所以我会举例说明。
示例一声明了两个对象:
Random random = new Random();
for (int i = 0; i < 10000000; i += 1){
Integer integer = new Integer(random.nextInt());
String string = integer.toString();
}
仅声明一个对象的示例二:
Random random = new Random();
for (int i = 0; i < 10000000; i += 1){
String string = (new Integer(random.nextInt())).toString();
}
在第二个示例中,仍然创建了 Integer 对象,但它在内存中的位置没有保存(我认为)。我知道将对象创建减少一个似乎微不足道,但在具有多次迭代的大循环中,将对象引用减半肯定是有益的。这种技术是否可以节省内存(即最小化垃圾收集)?
编辑:更改了示例以更好地说明问题。
最佳答案
Does this technique save any memory (i.e. minimize Garbage Collection)?
事实上,您在问两个不同的问题。答案是“否(实际上)”和“否”。
(这适用于问题的原始版本和更新版本。)
第一个答案需要一些解释。
在第一个示例中,如果这是在循环中,则 string
和integer
变量要么会多次超出范围,要么会被多次覆盖。 (在您的示例中,它们超出了范围。)
如果发生其中任何一种情况,变量的当前值将被“遗忘”,并且相应的对象将变得无法访问。
在第二个示例中,您没有输入 Integer
对象放入变量中,因此相应的对象可能会提前几纳秒变得无法访问。但由于此代码处于循环中,因此差异可以忽略不计。事实上,它可能是无法衡量的。
第二个答案更容易解释。仅当两个分配之一(即创建 new
的 Integer
语句或创建 Integer.toString()
的 String
内的语句)需要时,您的代码才会触发垃圾回收比立即可用的内存更多。由于两段代码执行相同的分配,因此 GC 运行的次数没有差异。
另一点是,在 Java 中如此详细地思考这些事情根本就是浪费时间。一般来说,垃圾收集器只负责处理事情。在这个具体的例子中,“优化”的最大理论优势在于单个Integer
对象可能会在垃圾收集周期中更早地被释放。该对象占用大约 16 个字节。这根本不值得考虑。
您所做的事情在业内被称为“过早优化”。不要在上面浪费时间。如果您需要优化,请等到您有了可用的程序并对其进行分析。然后将精力花在分析器认为有问题的部分上。
关于java - 最小化 Java 中的垃圾收集尝试(示例),我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/17769021/