“例如,如果您的计算机上有 1GB 内存(10 亿字节),那么您一次无法在内存中容纳超过 3200 万个 int 值或 1600 万个 double 值。”
int - 4 个字节
3200 万 x 4 = 1.28 亿字节
帮我理解一下,为什么我们不能适应 3200 万个 int 值,上面的 1.28 亿字节大约是 1GB 或 10 亿字节整体内存消耗的 1/10。
“例如,如果您的计算机上有 1GB 内存(10 亿字节),那么您一次无法在内存中容纳超过 3200 万个 int 值或 1600 万个 double 值。”
int - 4 个字节
3200 万 x 4 = 1.28 亿字节
帮我理解一下,为什么我们不能适应 3200 万个 int 值,上面的 1.28 亿字节大约是 1GB 或 10 亿字节整体内存消耗的 1/10。
这取决于您如何组织数据。在 Java 中,每个对象都有开销,这取决于 JVM,但通常是 8 或 16 个字节。因此,如果您将每个 int 值包装到一个对象中(如Integer
),那么您可能会超过 1GB。但是,如果你将它分配为一个int[]
数组,那么它应该很容易适应 1GB。
而且,这与问题并不严格相关,但反映了@Anony-Mousse 的评论,微控制器有JVM,我很确定这些 JVM 中的对象大小低于 8 字节(尽管我没有找到确切的数据)。
正如@Katona 所说,这取决于您是存储原始整数还是包装整数。
Anint
需要 4 个字节,adouble
需要 8 个字节,但通常的 Hotspot VM 中的对象Integer
和对象都需要 16 个字节。Double
假设您将它们存储为,则每个对象引用Integer[]
需要 4 个额外的字节。
现在,如果您使用例如 aTreeSet
或 aHashSet
事情会变得更糟。这些也将需要一个Entry
对象,该对象(在 32 位上,或带有压缩指针)应添加另外 16 个字节,加上 4 个(在 64 位上没有压缩指针的 8 个)字节用于内部存储中的对象引用。
因此,如果您将整数存储在 a 中,TreeSet<Integer>
您可能会用完仅 2800 万个整数和 1 GB RAM 的内存。
另一方面是显然并非所有内存都可用于存储对象数据。Java 还需要内存用于内务处理、类加载器,并且一些内存只是在段边界处“浪费”,并为将来使用做好准备。假设例如只有 50%-66% 可用于您“自己的”处置并且您有对象开销,那么上面的数字可能是正确的,并且碰巧在实践中导致问题,而不是理论上。