【问题标题】:With 256 MB RAM, what is the maximum length of double array we can create?使用 256 MB RAM,我们可以创建的双数组的最大长度是多少?
【发布时间】:2011-12-24 12:00:45
【问题描述】:

Code Ranch有这个问题:

28) 如果我们有 256 MB RAM,那么我们可以创建的双精度数组的最大长度是多少? (忽略jvm内存占用和一切 否则)

回答: Integer.MAX_VALUE 作为 length() 方法必须返回正确的 'int' 长度。

我不确定我是否理解他们提供的答案。据我所知,大多数实现使用 64 位作为双精度数,这意味着我们可以在 256 MB RAM 中容纳大约 4 194 304 个双精度数(减去开销)。

那么在 256 MB RAM 的环境中,双精度数组的最大长度怎么可能是 2147483647 呢?

下面的测试代码肯定会给我们OOM吧?:

public class test {
    public static void main(String[] args) {
        double[] d = new double[java.lang.Integer.MAX_VALUE - 8];
    }
}

【问题讨论】:

  • 你是怎么到达4 194 304的?这个数字乘以 64 位得到 32 MB。
  • 数组没有length() 方法。我只能假设提问者对他的措辞不够谨慎。

标签: java memory


【解决方案1】:

编辑:下面的答案假设问题是询问可以在问题中指定的 256MB 内分配的数组的大小。如果这不是问题的重点,那么没有明确的答案 - 因为最大长度将完全取决于分配给 JVM 的内存量, JVM 如何使用内存等。我们可能有 256MB 的内存,但运行带有 -Xmx64M 的 Sun JVM,所以可用的内存甚至少于 256MB。

所以要么问题不好,要么答案错误——或者很可能两者兼而有之。


Code Ranch 的答案绝对不正确:256MB 是 28 * 220 字节 - 即 228 字节。每个double 值占用8 个字节,因此即使不考虑对象和长度的任何开销,您可以在256MB 中存储的double 值的最大数量为223Integer.MAX_VALUE 是 231 - 1,显然要大得多。

(顺便说一下,double 使用 64 位的“大多数实现”不是问题 - 这是规范要求的。)

所以是的,如果您只有 256MB 可用内存,您的测试代码确实会出现 OOM。

鉴于该页面上的某些问题甚至没有答案,这个答案肯定是不正确的,而其他答案写得不好,我会完全忽略该页面。

【讨论】:

  • @artbristol:来自问题:“忽略占用的 jvm 内存和其他所有内容” - 我认为它包括其他虚拟内存。
  • 交换空间很少位于 RAM 中。
  • @LinusKleen:我不确定您要表达什么观点,但我阅读问题的方式是询问如果所有内存可用,您可以分配的数组的最大大小阵列为 256MB。这绝对是一个措辞不佳的问题 - 不幸的是,这与页面的其余部分一致。
  • “如果我们有 256 MB RAM 那么什么是......”我指的是 artbrisol 关于交换空间的问题。
【解决方案2】:

取决于您拥有的交换空间、操作系统所需的内存量、VM+程序的内存量......

所以没有确定的答案。

【讨论】:

  • 明确指出这些应该被忽略。
  • 交换空间与此有什么关系?您为 JVM 分配了一定数量的内存。在问题的上下文中,很明显 256MB 可用的。
  • 其实这个答案是正确的,或者至少比 Jon Skeet 的更准确。该问题没有说明使用的是什么 JVM,并且 JVM 可能能够使用它可以从操作系统分配的尽可能多的内存(即旧的 Microsoft VM 做到了这一点)。因此,JVM 可以成功分配一个太大而无法放入物理 RAM 的数组。
  • 问题是某些进程(例如操作系统)要求东西总是在物理内存中。忽略该计算机上运行的其他东西的问题是虚假的。
  • 操作系统必须兼顾。也许 JWM 会多一点或少一点
【解决方案3】:

理论上,您可以分配地址空间允许的所有内容——当您尝试实际使用该地址空间时,您可能会遇到问题。

所以,答案部分正确:如果你有一个 64 位操作系统( JVM),你的地址空间足够大,可以容纳整个世界,但是数组索引是整数,是最大值Java 中的整数确实是Integer.MAX_VALUE (2^31 - 1)。但是,对于 32 位操作系统,情况并非如此,因为可用地址空间的字节数不够大。

但是您实际可以写入的内容受到 RAM 数量的限制,因此 2^(28-3) == 2^25 是您可以在内存中容纳的双精度数,忽略其他所有内容。

【讨论】:

    猜你喜欢
    • 1970-01-01
    • 2010-09-07
    • 2013-09-11
    • 2021-11-15
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2019-05-17
    相关资源
    最近更新 更多