【问题标题】:Understanding memory allocation and GC in java了解java中的内存分配和GC
【发布时间】:2018-03-22 21:18:32
【问题描述】:
我正在尝试了解抓取收集算法的工作原理。我正在读这个article。据我了解,每次分配都发生在年轻一代。如果没有足够的可用空间Minor GC 会触发清理年轻代(Eden、S1、S2)。但现在想象我们有一些类:
public class TestYoungCrash{
private long l1;
private long l2;
//...
private long l100000000;
//tons of other fields
}
所以类的对象不适合年轻代,即使一代完全清楚。
然后会发生什么?标准化了吗?
【问题讨论】:
标签:
java
garbage-collection
【解决方案1】:
不可能有一个对象需要如此多的内存。但不是因为内存限制,而是出于更实际的原因——JVM 限制了每个类的字段数,见here:
类或接口可以声明的字段数受 ClassFile 结构的 fields_count 项的大小限制为 65535(第 4.1 节)。
你的班级不能有太多的字段,以至于你会炸毁记忆。我很确定:如果您启动 JVM 时堆太小,以至于包含 65535 个长字段的单个对象不适合... JVM 很可能甚至无法启动。
从这个意义上说,我们可以将您的问题改写为:当我创建的数组太大而无法放入提供给 JVM 的堆空间时会发生什么?然后你基本上回到这个question ...它说:OutOfMemoryError。
【讨论】:
-
-
-
嗯,实际上,大数组可能会绕过年轻代,直接分配到年老代。仅仅为了几个甚至一个数组实例而调整年轻代的大小并不是一个好的策略。此外,如果阵列幸存,绕过消除了复制成本。请参阅this Q&A 进行讨论。顺便说一句,可以想象即使是非数组对象也可能有那么大。单个类文件限制为 65535 个字段(实际上甚至更少),但类可以扩展其他类...
-