Java应用优化数据结构需基于内存实际占用,先用JOL分析对象真实开销(含头部、字段及对齐填充),再按字段顺序优化布局,并依场景替换低效集合类型。
Java应用优化数据结构不能靠猜测,得从内存实际占用出发——先看清对象占多少字、字段怎么排、集合有没有冗余,再针对性替换或重构。
JVM中每个对象有固定头部(标记字+类指针),加上字段对齐填充。比如一个只有两个int字段的类,看似8字节,实际可能占24字节(12字头+8字字段+4字填充对齐)。用JOL(Java Object Layout)工具可精确查看:
```java
System.out.println(ClassLayout.parseClass(MyObj.class).toPrintable());
```
重点观察:字段顺序是否导致大量填充?能否把long/double放前面、byte/boolean放后面,压缩空间?
不是所有场景都适合HashMap或ArrayList。常见替换路径:
boolean[]节省约8倍空间(位存储 vs 字节存储)List<Integer>,改用int[]或FastUtil的IntArrayList
有些写法表面简洁,实则悄悄放大内存占用:
立即学习“Java免费学习笔记(深入)”;
String.substring()在JDK 7u6前会共享原字符串char[],导致小子串拖着大数组不释放;现版本虽已修复,但new String(str)仍可能复制冗余char[]ArrayList<Object>存大量相同类型对象(如全是String),不如拆成多个原始数组(String[], int[]等),避免每项额外的引用字段和类型检查"key="+k+"&val="+v),会触发多次StringBuilder扩容和中间String对象,应复用StringBuilder或用MessageFormat预编译改完数据结构后,别只信理论值。用jmap生成堆快照:
```bash
jmap -dump:format=b,file=heap.hprof <pid>
```
再用Eclipse MAT或VisualVM打开,按“Group by Class”排序,重点关注:
• 实例数最多、总保留大小(Retained Heap)最高的类
• 同一类中Shallow Heap与Retained Heap差异大的对象(说明它持有了大量子对象)
• 是否还有大量包装类(Integer、Long等)实例——这是原始数组改造不到位的信号