String/byte 效率和内存行为

String/byte efficiency and memory behavior

我有一张这种格式的二维地图: (x,y,类型,索引) 从 Swing 应用程序输入到 jmonkeyengine 渲染器。 我用过:

String map_array[10000][1000];

示例:

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

这意味着在 x=100 和 y=200 的位置有一个索引为 8 的敌人 ("E")。 它的内存行为是这样的:

我用另一种方式做了:

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

示例:

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

与上例意义相同。 它的内存行为是这样的:

我的问题是:

  1. 为什么 String 有缓慢分配和反弹的奇怪行为(如您所见,尽管游戏 运行 流畅,但它达到最大值需要 2 多分钟)?
  2. 字节方式好像比较省内存,但是哪种方式更好呢?

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

  1. 不可变的:每次更改字符串时,都会在堆上创建一个新对象。
  2. Interned:由相同字符串文字定义的两个字符串自动共享相同的底层 char[](a = "F1"; b = "F1"; ab 共享 "F1")。这样可以节省内存。但是一旦不再使用 char[],它就会保留在缓存中以用于字符串文字。

在不知道程序在那段时间做了什么的情况下,我无法确定到底是什么导致了内存波动。但我的猜测是它与上面提到的那些东西和垃圾收集器有关。

您可以通过重复使用相同的常量字符串对象来避免不必要的分配:

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 已经在其场景图形节点中存储了对象类型和位置时,为什么还要存储任何东西?