字符串/字节效率和内存行为

时间:2015-10-12 18:58:52

标签: java memory jmonkeyengine

我有这种格式的2D地图: (X,Y,类型,索引) 这是从Swing应用程序输入到jmonkeyengine渲染器。 我用过:

String map_array[10000][1000];

示例:

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

这意味着在x = 100和y = 200的位置有一个指数为8的敌人(“E”)。 它的记忆行为是这样的:

Memory of String array

以我做的另一种方式:

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

示例:

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

其含义与上述示例相同。 它的记忆行为是这样的:

Memory of byte

我的问题是:

  1. 为什么String有缓慢分配和跳出的奇怪行为(因为你可以看到,虽然游戏运行顺利但它达到最大值超过2分钟)?
  2. 字节方法似乎消耗更少的内存,但哪种方式更好?

1 个答案:

答案 0 :(得分:1)

您的第一个声明String map_array[10000][1000]创建一个数组数组,其中包含指向String对象的指针。在Java中,字符串是

  1. 不可变:每次更改String时,都会在堆上创建一个新的Object。
  2. Interned:由相同字符串文字定义的两个字符串自动共享相同的底层字符[](a = "F1"; b = "F1"; ab共享“F1”)。这可以节省内存。但是一旦char []不再使用,它​​仍然保留在字符串文字的缓存中。
  3. 我不知道究竟是什么导致了内存波动而不知道程序在那段时间做了什么。但我的猜测是它与上面提到的那些东西和垃圾收集器有关。

    您可以通过重用相同的常量String对象来避免不必要的分配:

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

    第二个声明byte map_array[10000][1000][2]创建一个数组数组。没有什么魔法可以继续,也没有内存分配的开销来改变价值。

    你的 map_array 看起来很稀疏。是否有理由在地图上表示每个字段?如果是这样,你不能使用仅存储正在使用的字段的HashMap吗? 当jMonkeyEngine已经在其Scenegraph节点中存储对象类型和位置时,为什么甚至存储任何内容?