堆內存 128KB-500KB、無 JIT、GC 停頓明顯、**對象頭開銷大 (8-12 字節/對象)、方法調用開銷大**。
核心策略:**用基本類型數組替代對象圖,用整數位運算替代枚舉/對象狀態,靜態分配替代動態創建。**
class Actor {
int hp, mp, money, atk, def;
int x, y, row, col;
int action, dir;
// 10+ 字段,每個實例 100+ 字節,100 個實例 = 10KB+ 對象頭
}
// 所有角色屬性集中在一個二維數組:actor[id][attrIndex] final int MAX_ACTORS = 100; final int ATTR_COUNT = 12; int[][] actors = new int[MAX_ACTORS][ATTR_COUNT]; // 屬性索引常量 (編譯期常量內聯,零開銷) static final int HP=0, MP=1, MONEY=2, ATK=3, DEF=4; static final int X=5, Y=6, ROW=7, COL=8; static final int ACTION=9, DIR=10, STATE=11; // 訪問範例 int hp = actors[actorId][HP]; actors[actorId][X] += dx[actors[actorId][DIR]]; // 新增屬性只需擴展 ATTR_COUNT 和新增常量,零代碼修改
| 指標 | 對象版 | 數組版 | 提升 |
|---|---|---|---|
| 100 實例內存 | ~15 KB | ~4.8 KB (100×12×4B) | 68% 減少 |
| GC 壓力 | 100 對象 | 1 數組對象 | 99% 減少 |
| 字段訪問速度 | 方法調用/字節碼 getfield | 數組索引 iaload | 更快 (JIT 易優化) |
| 擴展性 | 修改類、重新編譯 | 擴展數組、新增常量 | 熱更新友好 |
地圖不僅是靜態圖塊,還包含動畫幀、切換計時、可行走性、觸發事件等動態屬性。
// 屬性層索引
static final int TILE_ID=0; // 當前圖塊 ID
static final int FRAME=1; // 動畫當前幀
static final int FRAME_TIMER=2; // 幀切換倒計時
static final int WALKABLE=3; // 0 不可走, 1 可走
static final int TRIGGER=4; // 0 無, >0 對話/事件 ID
static final int LAYER2=5; // 疊加層 (如屋頂、特效)
// 初始化
int[][][] map = new int[MAP_ROWS][MAP_COLS][6];
// 更新邏輯 (每幀調用)
void updateMapAnimations() {
for (int r=0; r 0) {
if (--map[r][c][FRAME_TIMER] == 0) {
map[r][c][FRAME] = (map[r][c][FRAME] + 1) % MAX_FRAMES;
map[r][c][FRAME_TIMER] = FRAME_DELAY;
}
}
}
// 渲染邏輯
void renderMap(Graphics g, int camX, int camY) {
for (int r=0; r
對比:對象版地圖的災難
- 每個格子一個
Tile 對象 → 100×100 地圖 = 10,000 對象,內存爆炸。
- 動畫更新需遍歷對象列表,緩存未命中嚴重。
- 三維數組:連續內存、CPU 緩存友好、批量操作可向量化。
技巧三:位掩碼壓縮布爾/枚舉狀態
// 單個 int 存 32 個布爾標誌
static final int FLAG_VISIBLE = 1 << 0;
static final int FLAG_SOLID = 1 << 1;
static final int FLAG_DEADLY = 1 << 2;
static final int FLAG_NPC = 1 << 3;
int[] entityFlags = new int[MAX_ENTITIES];
// 設置/檢測
entityFlags[id] |= FLAG_VISIBLE; // 設置可見
if ((entityFlags[id] & FLAG_SOLID) != 0) { /* 碰撞 */ } // 檢測固體
entityFlags[id] &= ~FLAG_VISIBLE; // 清除可見
現代映射:這些技巧在今日仍有效
場景 現代對應技術
高性能遊戲/模擬 (ECS 架構) Structure of Arrays (SoA)、EntityComponentSystem、Vectorized 數據布局
大數據列式存儲 Parquet/ORC 列式格式、Apache Arrow 內存佈局
GPU Compute / Shader Structure of Arrays 緩存、SSBO/UBO、texture buffer
嵌入式/實時系統 靜態分配、位域、constexpr、無堆分配
高頻交易/數據庫 無鎖環形緩衝、struct of arrays、內存對齊
總結:J2ME 遊戲優化的核心哲學
- 數據導向設計 (DOD):關注數據在內存中怎麼佈局、怎麼流動,而非對象邊界。
- 基本類型優先:
int[] > Integer[] > List<Integer> > List<Object>。
- 靜態 > 動態:編譯期決定佈局,運行期零分配。
- 位運算是免費的:壓縮狀態、分支消除、SIMD 友好。
J2ME 時代的「生存技巧」,如今是高性能計算的「核心競爭力」。