我决定进行这样的实验。
public class Main {
public static final int mew = Integer.MAX_VALUE;
public static final String message = "A0yj8,fghfgh02fdgdrthrtfjfghfghfj";
public ArrayList<StringBuilder> list = new ArrayList<>();
public static void main(String[] args) throws InterruptedException {
Main main = new Main();
final StringBuilder sb = new StringBuilder();
sb.append(message);
while (true){
main.clear();
Thread.sleep(1000);
main.addposition(sb.toString());
}
}
public void clear(){
for (StringBuilder sb : this.list){
sb.setLength(0);
}
list.clear();
list = new ArrayList<>(10);
}
public void addposition(String s ){
for (int i = 0 ; i < mew; i ++){
this.list.add(new StringBuilder().append(s+1));
}
}
}
几秒钟后,资源监视器变为红色,并且已用内存飞得远远超过 1 GB。也许我做错了什么?
他们到处喊着必须使用 StringBuilder,因为 String 是不可更改的。
循环中的方法
addposition将对象添加到列表中 20 亿次,每个对象至少包含 34 个字符(+StringBuilder列表中每个对象和元素的开销this.list)。那些。在第一次调用addposition数据本身时,至少有 34 * 2 * MAX_INT = 136 GB,并且为所有这些分配了内存。他做什么都没关系
clear。通常,要释放内存,确保没有对对象的单个普通引用就足够了。在这种情况下,它将被垃圾收集器收集。它不必立即发生(因为 JVM 试图减少垃圾收集的开销),但是如果程序请求内存分配并且它被垃圾占用,那么
OutOfMemoryError在它发生之前将完成一次完整的垃圾收集。那些。在这种情况下(如果我们忽略正在添加的 20 亿个对象这一事实,并假设它们的数量较少,因此它们都适合 JVM 的可用内存),这就
list.clear足够了,因为 对已创建对象的唯一引用StringBuilder存储在列表中this.list。该操作clear将清除列表,并且对这些对象的所有引用都将丢失。