Is there a low level difference between int [large] [small] or int [small] [large] in Java?

This question will probably require some compilers to answer. I am currently working on a project where I will create an array that can be

int[2][veryLargeNumber] 

or

 int [veryLargeNumber][2] 

This has nothing to do with logic, but I thought that the shape (and therefore size) in memory might be different (maybe the question should be, are the compilers smart enough to reorder arrays according to them)?

+60
java arrays memory multidimensional-array jvm
Feb 23 '16 at 11:30
source share
4 answers

Java actually implements only one-dimensional arrays. It has multidimensional types, but two-dimensional arrays are actually implemented as an array of arrays. Each array has an overhead of about 16 bytes. You are better off with int[2][x] minimize overhead.

You can completely avoid this problem by using helper methods.

 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; } 

To ensure this for itself, each hash object is unique, generates a hashCode, which is stored in its Object header.

You can see from http://ideone.com/oGbDJ0 that each nested array is on its own.

 int[][] array = new int[20][2]; for (int[] arr : array) { System.out.println(arr); } 

prints the internal representation of int[] , which is [I followed by @ , followed by hashCode () stored in the header. This is not, according to some, the address of the object. An address cannot be used as a hashCode, since an object can be moved at any time by the GC (unless you have a JVM that never moves objects)

 [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 

You can see how much memory is used if you disable TLAB with -XX:-UseTLAB https://github.com/peter-lawrey/Performance-Examples/blob/master/src/main/java/vanilla/java/memory /ArrayAllocationMain.java

 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(); } 

prints

 Space used by int[200][2] is 5720 bytes Space used by int[2][200] is 1656 bytes 
+53
Feb 23 '16 at 11:35
source share

Interesting question, I ran a simple program

 int N = 100000000; long start = System.currentTimeMillis(); int[][] a = new int[2][N]; System.out.println(System.currentTimeMillis() - start + " ms"); 

The result is 160 ms . Then I launched another option

 int N = 100000000; long start = System.currentTimeMillis(); int[][] a = new int[N][2]; System.out.println(System.currentTimeMillis() - start + " ms"); 

The result is 30897 ms . So the first option seems a lot better.

+23
Feb 23 '16 at 11:38
source share
  int[2][veryLargeNumber] 

creates two arrays with verlarnumber elements
while

  int[veryLargeNumber][2] 

creates a very large number of arrays having two elements.

Note. When creating an array, there is overhead. therefore, the first option is preferred

+11
Feb 23 '16 at 11:44
source share

In short, int[2][veryLargeNumber] is the best approach.

Recommended Peter ( int[] array = new int[2 * veryLargeNumber]; ) is even better, or if your memory is your problem, then you can use longs instead of integers ( long[] array = new long[veryLargeNumber]; ) and bitwise operators, or better yet, use caching whenever possible.

Caution! The representation [I@106d69c in most JDK / JRE distributions (Sun and Oracle) is given by System.identityHashCode() , and it is not guaranteed to be unique for every object. Therefore, you cannot rely on System.out.println(array); to check the uniqueness of an array object.

+1
Feb 23 '16 at 21:57
source share



All Articles