javamemoryjmonkeyengine

String/byte efficiency and memory behavior


I have a 2D map in this format: (x,y,type,index) Which is fed into jmonkeyengine renderer from a Swing app. I used:

String map_array[10000][1000];

Example:

map_array[100][200]="E8";

Which means in position x=100 and y=200 there is an Enemy ("E") with index of 8. Its memory behavior is like this:

Memory of String array

and in another way I made:

byte map_array[10000][1000][2];

Example:

map_array[100][200][0]='E';
map_array[100][200][1]='8';

Which has the same meaning of above example. Its memory behavior is like this:

Memory of byte

My questions are:

  1. Why String has strange behavior of slow allocating and bounces (as you can see it gets more than 2 minutes to reach maximum though the game is running smoothly)?
  2. Byte method seems to be less memory consuming but which way is better?

Solution

  • Your first declaration String map_array[10000][1000] creates an array of arrays with pointers to String objects. In Java the Strings are

    1. Immutable: Each time you change a String, a new Object is created on the heap.
    2. Interned: Two Strings which were defined by the same string literal automatically share the same underlying char[] (a = "F1"; b = "F1"; a and b share "F1"). This can save memory. But once a char[] is not used anymore, it remains in the cache for string literals.

    I can't tell what exactly causes the memory fluctuations without knowing what the program does during that time. But my guess is it has to do with those things mentioned above and the Garbage Collector.

    You can avoid unnecessary allocations by reusing the same constant String object:

    static final String F1 = "F1";
    map_array[10][20] = F1;
    map_array[20][40] = F1;
    

    The second declaration byte map_array[10000][1000][2] creates an array of arrays of arrays. No magic going on and no overhead of memory allocation to change values.


    Your map_array looks like it's very sparsely populated. Is there a reason for representing every single field on the map? If so, can't you use a HashMap which only stores the fields in use?
    Why even store anything when the jMonkeyEngine already stores object type and position in its Scenegraph Nodes?