UPD 21.11.2017:该错误已在JDK中修复,请参阅Vicente Romero的评论
摘要:
如果for语句用于任何Iterable实现,则集合将保留在堆内存中直到当前作用域(方法,语句体)的结尾,并且即使您没有对集合和应用程序的任何其他引用也不会进行垃圾回收需要分配一个新的内存.
http://bugs.java.com/bugdatabase/view_bug.do?bug_id=JDK-8175883
https://bugs.openjdk.java.net/browse/JDK-8175883
例子:
如果我有下一个代码,它会分配一个包含随机内容的大字符串列表:
import java.util.ArrayList;
public class IteratorAndGc {
// number of strings and the size of every string
static final int N = 7500;
public static void main(String[] args) {
System.gc();
gcInMethod();
System.gc();
showMemoryUsage("GC after the method body");
ArrayList<String> strings2 = generateLargeStringsArray(N);
showMemoryUsage("Third allocation outside the method is always successful");
}
// main testable method
public static void gcInMethod() {
showMemoryUsage("Before first memory allocating");
ArrayList<String> strings …Run Code Online (Sandbox Code Playgroud) 我们目前有在 Java 8 中编译的代码,但我们正在 Java 11 VM 上运行它。现在我们也在尝试将我们的代码移动到 Java 11 编译时。想知道 Java 8 中的编译代码与 Java 11 中的编译代码在性能方面是否有任何好处,因为两个编译器都会生成不同的类文件(字节码)?一个在效率方面与另一个有何不同?