【问题标题】:How much memory does an int take on Sun's 64-bit JVM?在 Sun 的 64 位 JVM 上,一个 int 占用多少内存?
【发布时间】:2011-02-23 07:00:42
【问题描述】:

我知道 Java 的实现会尽其所能向开发人员隐藏这些信息,但我正在构建一个不依赖于第三方库的内存绑定算法,因此这些信息会派上用场。

特别是,我将许多大型int[] 数组分配为实例变量。我将很快研究更紧凑的表示,但现在我想知道一个普通数组使用了多少空间。

【问题讨论】:

    标签: java memory memory-management


    【解决方案1】:

    好吧,int 字段可能由于填充而最终占用超过 4 个字节......但基本上它是 4 个字节(32 位)。至于它是否确实占用超过 4 个字节,您必须进行试验才能找到答案。对于对象中的字段,这相当容易做到;对于基于堆栈的 int 值更难。

    例如,int 的大数组总是会占用大约 4 倍的长度(+ 少量的长度开销等)。我不相信元素之间会应用填充——尽管验证这一点相对容易。 Runtime.totalMemory() - Runtime.freeMemory() 返回的值只应谨慎使用,但如果您在一次运行中分配 100 万个整数的数组,然后在另一次中分配 200 万个整数,然后是 300 万个整数,等等,应该相当清楚发生了什么。

    示例代码:

    public class Test {
      public static void main(String[] args) {
        int size = Integer.parseInt(args[0]);
    
        long before = getUsedMemory();
        int[] array = new int[size];
        long after = getUsedMemory();
    
        long difference = after - before;
        System.out.println("Total difference: " + (after - before));
        System.out.println("Per element: " + ((double) difference) / size);
        System.out.println(array); // Make sure the array isn't GC'd early
      }
    
      private static long getUsedMemory() {
        Runtime rt = Runtime.getRuntime();
        return rt.totalMemory() - rt.freeMemory();
      }
    }
    

    在我的机器上,尝试使用 100000、2000000 和 3000000 会为所有运行提供“4*size + 16”字节。

    【讨论】:

    • 谢谢!我只是按照你的建议澄清了我的问题:)
    • @abahgat:我已经编辑了我的问题,使其更加清晰。
    【解决方案2】:

    只是一个int 本身?这可能取决于它与什么相邻,等等。或者您的意思是int 的数组?我有 99% 的把握在所有合理的 JVM 实现中都会占用 4 个字节(加上数组对象本身的一些固定开销)。

    long before = Runtime.getRuntime().freeMemory();
    int foo[] = new int[123456];
    System.out.println("Approximate bytes per int: "
      + (before - Runtime.getRuntime().freeMemory())/(float)123456);
    

    报告:

    每个 int 的近似字节数:4.0001945

    【讨论】:

    • 我应该补充一下,这是使用 64 位 JVM,正如您所想的那样。
    【解决方案3】:

    【讨论】:

    • 当然,但是只要符合规范,兼容的实现可以使用大于 32 的任意位数来表示它们。例如,布尔值在规范中只有两种状态,但通常它们肯定由多于 1 位表示。
    • 这只是一个规范,它只保证如果您尝试将一些数字放入超过 32 个字节的int 中,它会以某种方式抱怨或行为不端。但是在它内部可以以任何可能的方式实现,即使为每个 int 分配 1 Gb 并且只使用 4 个字节。虽然这肯定很荒谬,但有可能:)
    猜你喜欢
    • 2011-10-29
    • 2012-09-08
    • 2017-02-06
    • 1970-01-01
    • 2011-04-13
    • 2012-07-06
    • 2012-08-10
    • 2012-02-13
    • 1970-01-01
    相关资源
    最近更新 更多