0

So I'm working on a Java program that is going to be updating a 2D array many times per second. Originally, I was copying the entirety of the array using System.arrayCopy(), but that was clearly a bad idea since I'm only updating one row at a time. Instead I decided to just have a "pointer" to the virtual "zero" of the array. Anyway, I also want to be able to support dynamic sizing, and it occurred to me that the easiest way to do this might be to have one array that stays the same size, and then have a number that indicates the maximum length of the virtual array. I found myself thinking that could be a waste of memory though

The above information is just so someone can tell me if I'm doing something completely ridiculous.

TL;DR = if I do the following...

int[][] data = new int[2000][]; // 2000 would be the max
for(int i=0; i<10; i++) {
    data[i] = new int[10];
}

...how much memory have I used in addition to the hundred ints I actually initialized? Would it just be the 4 bytes for each null reference?

hakre
  • 193,403
  • 52
  • 435
  • 836
MalcolmOcean
  • 2,807
  • 2
  • 29
  • 38

3 Answers3

2

Its 4 bytes for every null reference plus 8-16 bytes for the header. Most 64-bit JVMs use 32-bit references up to about 30 GB of heap size.

Peter Lawrey
  • 525,659
  • 79
  • 751
  • 1,130
1

Consider using a java.util.List that contains other Lists as elements instead of a 2D array (which is an array that contains other arrays in Java).

The Lists

  • will be more intelligent out of the box
  • will automatically support dynamic sizing (in a performance-optimized manner)
  • can contain nulls (like the uninitialized subarrays)
  • you can tweak their performance according to your requirements (ArrayList vs LinkedList vs CopyOnWriteArrayList)...
lbalazscs
  • 17,474
  • 7
  • 42
  • 50
  • Would the list perform well if I have to access thousands of elements per second? – MalcolmOcean Aug 21 '12 at 19:25
  • You should always measure, but my guess is that thousands of gets per second is not that much for an ArrayList. Read this: http://stackoverflow.com/questions/1182892/java-performance-arraylists-versus-arrays-for-lots-of-fast-reads – lbalazscs Aug 21 '12 at 20:24
  • And this: http://stackoverflow.com/questions/716597/array-or-list-in-java-which-is-faster – lbalazscs Aug 21 '12 at 20:31
-1

Yes, you will use 2000*sizeof(ptr) bytes for the first line, and 10*10*sizeof(int) for the loop (plus object overhead).

Keith Randall
  • 22,985
  • 2
  • 35
  • 54
  • This is not really true in C/C++ as allocated memory has a header and alignment. – Peter Lawrey Aug 21 '12 at 17:55
  • @PeterLawrey: the question wasn't about C/C++. – Keith Randall Aug 21 '12 at 20:01
  • In that case, I don't understand your answer. there is no `sizeof()` or pointers in Java or anything like it. The size of a *reference* can be different for different programs running on the same JVM. – Peter Lawrey Aug 21 '12 at 20:03
  • @PeterLawrey: Byte `sizeof(ptr)`, I mean size of a reference. Generally speaking, it is 8 bytes for 64-bit JVMs and 4 bytes for 32-bit JVMs (just like C, hence my notation). I think that's a reasonable simplification for the OP (i.e. ignoring the more complicated reality of various optimizations the JVM does). – Keith Randall Aug 21 '12 at 20:08
  • That is true, but most JVMs use 32-bit references these days unless their heap is 32 GB or more, so for simplicity I just say its 32-bit. Would +1, but reached my vote limit. ;) – Peter Lawrey Aug 21 '12 at 20:12