这个问题可能需要一些编译器知识来回答。我目前正在一个项目中,我将在其中创建一个数组
int[2][veryLargeNumber] 要么
int [veryLargeNumber][2] 从逻辑上讲,这没有什么区别,但是我认为内存中的形式(以及大小)可能会有所不同(也许问题应该是,编译器是否足够聪明,可以重新排列数组以适合它们)? 问题来源于stack overflow
Java实际上仅实现一维数组。它具有多维类型,但是二维数组实际上是作为数组的数组实现的。每个阵列的开销约为16个字节。您最好int[2][x]将开销降到最低。
您可以通过使用辅助方法完全避免此问题。
final int[] array = new int[2 * veryLargeNumber];
public int get(int x, int y) { return array[idx(x, y)]; }
public void set(int x, int y, int val) { array[idx(x, y)] = val; }
private int idx(int x, int y) { return x * 2 + y; // or x * veryLargeNumber + y; } 为了给自己提供此功能,每个对象散列一个唯一的哈希表,并生成hashCode,并将其存储在其Object标头中。
您可以从http://ideone.com/oGbDJ0看到每个嵌套数组本身就是一个对象。
int[][] array = new int[20][2]; for (int[] arr : array) { System.out.println(arr); } 打印的内部表示int[],其[I由随后@接着哈希码()存储在头中。这不是某些人认为的对象的地址。该地址不能用作hashCode,因为GC可以随时移动对象(除非您有一个永远不会移动对象的JVM)。
[I@106d69c [I@52e922 [I@25154f [I@10dea4e [I@647e05 [I@1909752 [I@1f96302 [I@14eac69 [I@a57993 [I@1b84c92 [I@1c7c054 [I@12204a1 [I@a298b7 [I@14991ad [I@d93b30 [I@16d3586 [I@154617c [I@a14482 [I@140e19d [I@17327b6 如果使用https://github.com/peter-lawrey/Performance-Examples/blob/master/src/main/java/vanilla/java/memory/ArrayAllocationMain.java关闭TLAB,则可以看到使用了多少内存。-XX:-UseTLAB
public static void main(String[] args) {
long used1 = memoryUsed();
int[][] array = new int[200][2];
long used2 = memoryUsed();
int[][] array2 = new int[2][200];
long used3 = memoryUsed();
if (used1 == used2) {
System.err.println("You need to turn off the TLAB with -XX:-UseTLAB");
} else {
System.out.printf("Space used by int[200][2] is " + (used2 - used1) + " bytes%n");
System.out.printf("Space used by int[2][200] is " + (used3 - used2) + " bytes%n");
}
}
public static long memoryUsed() { Runtime rt = Runtime.getRuntime(); return rt.totalMemory() - rt.freeMemory(); } 版画
Space used by int[200][2] is 5720 bytes Space used by int[2][200] is 1656 bytes
版权声明:本文内容由阿里云实名注册用户自发贡献,版权归原作者所有,阿里云开发者社区不拥有其著作权,亦不承担相应法律责任。具体规则请查看《阿里云开发者社区用户服务协议》和《阿里云开发者社区知识产权保护指引》。如果您发现本社区中有涉嫌抄袭的内容,填写侵权投诉表单进行举报,一经查实,本社区将立刻删除涉嫌侵权内容。