繁体   English   中英

N 个元素的一维数组是否需要与 2D[m][n] 相同的内存量,m*n=N

[英]Does a 1D array of N elements need the same amount of memory as 2D[m][n], m*n=N

这是有关Java中内存分配的问题。

假设我有一个整数数组 A[100] 和另一个整数数组 B[10][10]。 他们在 Java 中需要相同数量的内存还是不同? 如果是后者,有什么区别,它是如何随 N 增长的?

我在这里只讨论 N 是正数的 2 的幂,所以我们在这里讨论平方二维数组及其可能的一维表示。

明确地说,没有。

在 C/C++ 中,二维数组在“一个块”中为二维数组分配所有内存。

在 Java 中,二维数组是一个“数组数组”。 一维数组被分配在一个chunk中,但一维数组可能是分散的。 此外,“外部”数组(第二维)也需要堆内存,用于存储对一维数组的引用。

因此,如果分配一个维度为m (外部)和n (内部)的二维数组,Java 将创建一个包含m元素的数组和每个包含n元素的m数组。 外部数组只存储对m内部数组的引用。

此页面对 Java 中的多维数组进行了很好的解释和可视化。

这是对@Turing85 答案的实证确认,以及对开销的测量。 该程序交替分配和释放一个包含一百万个元素的数组或一个 int[1000][1000],报告每一步使用的内存量。 它很快就归结为:

Neither: 291696
1D: 4291696
Neither: 291696
2D: 4311696

显示了用于 2D 情况的额外 20,000 字节内存。

这是程序:

public class Test {
  public static void main(String[] args) {
    int M=1000;
    for(int i=0; i<10; i++){
      System.out.println("Neither: "+inUseMem());
      int[] oneArray = new int[M*M];
      System.out.println("1D: "+inUseMem());
      oneArray = null;
      System.out.println("Neither: "+inUseMem());
      int[][] twoArray = new int[M][M];
      System.out.println("2D: "+inUseMem());
      twoArray = null;
    }
  }

  private static long inUseMem() {
    System.gc();
    return Runtime.getRuntime().totalMemory()
        - Runtime.getRuntime().freeMemory();
  }
}

使用实际数组大小在感兴趣的系统上运行此程序应显示使用二维数组的成本。 如果数组真的总共有大约 10,000 个元素,那么最好采用使代码更具可读性的方法。

当使用“new”创建对象时,会在堆上分配内存并返回引用。 对于数组也是如此,因为数组是对象。

  1. 一维数组

int arr[] = new int 3 ; int[] arr 只是对 3 个整数数组的引用。 如果你创建一个包含 10 个整数的数组,它是一样的——一个数组被分配并返回一个引用。

Java 中的一维数组

  1. 二维数组

实际上,我们只能在 Java 中拥有一维数组。 二维数组基本上只是一维数组的一维数组。

int[ ][ ] arr = new int[3][ ];
arr[0] = new int[3];
arr[1] = new int[5];
arr[2] = new int[4];

Java 中的二维数组

多维数组使用命名规则。

正如您所观察到的,在管理二维数组时,需要额外的一维数组,因此就内存而言,大小不同,但从用户看来,两者的大小相同。

图片取自本网站

暂无
暂无

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM