Java 一个数组占用多少空间?

Java 一个数组占用多少空间?,java,arrays,Java,Arrays,如果我创建10个整数和一个10的整数数组,占用的总空间会有什么不同吗 我必须创建一个包含数百万条记录的布尔数组,因此我想了解数组本身将占用多少空间。就RAM空间而言,java中没有真正的区别。既有整数也有int。假设您指的是int,整数数组被视为对象,对象具有元数据,因此10个整数的数组将占用10个以上的整数变量一些粗略的下限计算: 每个整数占用四个字节40字节10 int数组占用每个组件的四个字节加上四个字节来存储长度,再加上四个字节来存储对它的引用48字节(+可能需要一些填充,以便在8字节边

如果我创建10个整数和一个10的整数数组,占用的总空间会有什么不同吗


我必须创建一个包含数百万条记录的布尔数组,因此我想了解数组本身将占用多少空间。

就RAM空间而言,java中没有真正的区别。

既有整数也有int。假设您指的是int,整数数组被视为对象,对象具有元数据,因此10个整数的数组将占用10个以上的整数变量

一些粗略的下限计算:

每个整数占用四个字节40字节10

int数组占用每个组件的四个字节加上四个字节来存储长度,再加上四个字节来存储对它的引用48字节(+可能需要一些填充,以便在8字节边界对齐所有对象)

一个整数至少占用8个字节,加上另外四个字节来存储对它的引用十张至少120张


整数数组至少占用10个整数的120字节加上长度的4字节,然后可能需要一些填充来对齐。加上四个字节来存储对它的引用。(@Marko报告说,他甚至测量了每个插槽大约28个字节,因此对于一个10字节的数组来说,这将是280个字节)。

一个整数数组表示为保存整数的内存块和一个对象头。对于32位JVM,对象头通常采用3个32位字,但这取决于平台。(标头包含一些标志位、对类描述符的引用、基本锁信息的空间以及实际数组的长度。加上填充。)

因此,10个整数的数组可能会占用
13*4
字节的区域

对于
整数[]
,每个整数对象都有一个2字的标题和一个包含实际值的1字字段。您还需要添加填充,以及1个字(或64位JVM上的1到2个字)作为引用。这通常是数组中每个元素5个字或20个字节。。。除非某些整数对象出现在数组中的多个位置


注:

  • 在64位JVM上实际用于引用的字数取决于是否使用“压缩的OOP”
  • 在某些JVM上,堆节点以16字节的倍数分配。。。这会增加空间利用率(例如,上面提到的填充物)
  • 如果获取一个对象的标识hashcode,并且它在下一次垃圾收集中幸存下来,那么它的大小会膨胀至少4个字节以缓存hashcode值
  • 除了上面列举的可变性来源外,这些数字都是特定于版本和供应商的

  • 如果使用数组,则有11个对象、10个整数和数组,再加上数组中有其他元数据。因此,使用数组将占用更多的内存空间


    现在说真的。这类问题实际上是在工作面试和考试中出现的,这表明你有什么样的面试官或老师。。。在虚拟机和操作系统中有这么多的抽象层,思考这些东西有什么意义?微优化内存

    根据您的评论,如果使用数组,则不会有太大区别。阵列本身的功能将使用可忽略不计的内存量。存储的对象将使用所有其他内存

    编辑:您需要了解的是布尔包装器和布尔基元类型之间的区别。包装类型通常会比原语占用更多的空间。因此,对于记录任务,请尝试使用原语


    正如您所说,在处理记录任务时要记住的另一件事是Java自动装箱。如果您在遍历整个阵列的函数中无意中使用此选项,则会对性能造成重大影响。

    您可以做的是测量:

    public static void main(String[] args) {
      final long startMem = measure();
      final boolean[] bs = new boolean[1000000];
      System.out.println(measure() - startMem);
      bs.hashCode();
    }
    private static long measure() {
      final Runtime rt = Runtime.getRuntime();
      rt.gc();
      try { Thread.sleep(20); } catch (InterruptedException e) {}
      rt.gc();
      return rt.totalMemory() - rt.freeMemory();
    }
    
    当然,这与标准免责声明是一致的:
    gc()
    没有特别的保证,所以重复几次,看看是否得到了一致的结果。在我的机器上,答案是每
    布尔值一个字节

    我的意思是,如果我创建10个整数和10的整数数组,会有 总占用空间的任何差异

    最后一个“+1整数”用于数组的索引(数组可以容纳2147483647个数据量,这是一个整数)。这意味着您在声明数组时,可以说:

    int[] nums = new int[10];
    

    实际上,您从内存中保留了11 int的空间。10表示数组元素,+1表示数组本身。

    这不必对老师/面试官产生不良影响

    您对内存中变量的大小和对齐方式的关注程度取决于您需要代码的性能。例如,如果您的软件处理交易(EFT/stock market),这非常重要

    内存中变量的大小、对齐方式和打包方式可能会影响CPU缓存命中/未命中,这可能会影响代码的性能达100倍

    只要你负责任地使用提高性能的技巧,了解低水平的情况并不是一件坏事


    例如,我来到这个帖子是因为我需要知道这个问题的答案,因此,我可以调整原语数组的大小以填充CPU缓存线的整数倍,因为我需要在这些原语数组上执行计算的代码快速执行,因为我有一个有限的窗口,我需要在其中为结果的使用者准备计算。

    是的,数组是一个对象,因此,它不仅仅具有价值。数组将占用更多空间。可能是这样,但值得您花时间思考吗?看看这个,我想知道,如果我创建一个包含数百万条记录的布尔数组,数组将占用多少空间。检查评论和其他答案。+1有很高的相对差异,但除非你经常这样做,否则它不会对你的申请产生真正的影响
    int[] nums = new int[10];