5

引用算法第 4 版中的以下内容

“例如,如果您的计算机上有 1GB 内存(10 亿字节),那么您一次无法在内存中容纳超过 3200 万个 int 值或 1600 万个 double 值。”

int - 4 个字节

3200 万 x 4 = 1.28 亿字节

帮我理解一下,为什么我们不能适应 3200 万个 int 值,上面的 1.28 亿字节大约是 1GB 或 10 亿字节整体内存消耗的 1/10。

4

2 回答 2

4

这取决于您如何组织数据。在 Java 中,每个对象都有开销,这取决于 JVM,但通常是 8 或 16 个字节。因此,如果您将每个 int 值包装到一个对象中(如Integer),那么您可能会超过 1GB。但是,如果你将它分配为一个int[]数组,那么它应该很容易适应 1GB。

而且,这与问题并不严格相关,但反映了@Anony-Mousse 的评论,微控制器有JVM,我很确定这些 JVM 中的对象大小低于 8 字节(尽管我没有找到确切的数据)。

于 2013-08-16T16:34:51.187 回答
2

正如@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% 可用于您“自己的”处置并且您有对象开销,那么上面的数字可能是正确的,并且碰巧在实践中导致问题,而不是理论上。

于 2013-08-16T18:26:37.797 回答