选对基本类型可从源头节省内存:优先使用byte、short、int、long按数据范围选取,float替代double省4字节,避免包装类减少对象头开销,集合用原生数组替代。

选对基本类型,从源头省空间
Java八种基本类型直接存值、栈上分配、无对象头开销,是内存优化的起点。关键不是“用哪个顺手”,而是“够用且最小”。
-
整数类型按范围选:年龄、状态码、HTTP状态码等固定小值(0–127)优先用
byte;传感器采样值、ID段偏移量(-32k~32k)可用short;日常计数、索引、ID主键等默认用int;时间戳、大ID、金融累计值才升到long -
浮点类型看精度需求:科学计算、金融风控等必须高精度场景用
double;图形渲染坐标、传感器原始读数、日志耗时毫秒级统计等可接受误差的场景,用float能省4字节/变量 -
别为省字节强行降级:比如用
short存用户ID,但业务扩展后ID超32767,反而引发溢出错误和后期重构成本——类型选择要留合理余量,而非极限压缩
基本类型优先,慎用包装类
包装类(Integer、Long 等)本质是堆上对象,每个实例至少占用12字节对象头 + 实际字段 + 对齐填充。高频使用时,代价远超想象。
- 集合中存大量数值时,避免
List<integer></integer>,改用int[]或第三方库如 Agrona 的IntArrayList,内存可减少50%以上 - 方法参数或返回值需泛型兼容时,优先用
int传参,仅在必须装箱处调用Integer.valueOf(x)(它复用 -128~127 缓存),禁用new Integer(x) - 局部循环变量、临时计算值一律用基本类型,例如
for (int i = 0; i ,比 <code>for (Integer i : list)更轻量
字符串操作不拼接,内存泄漏早预防
String 表面简单,实则暗藏内存陷阱。Java 9+ 虽已优化为 byte[] + coder,但不当用法仍会快速堆积临时对象。
- 循环内字符串拼接必须用
StringBuilder(单线程)或StringBuffer(多线程),禁止用+=——每次拼接都生成新对象,10万次循环可能创建10万个String实例 - 从数据库或文件读取大批量文本时,若内容重复率高(如日志级别、状态枚举值),考虑调用
String.intern()进入常量池复用;但注意 JDK 7+ 后常量池在堆中,滥用会导致老年代膨胀 - 接收外部输入构造String时,避免保留原始大数组引用。例如
new String(byteArray)在 Java 8 及以前可能共享底层char[],建议显式拷贝:new String(byteArray).intern()或直接用String.valueOf(byteArray)
集合与对象生命周期要“看得见”
类型选对只是第一步,数据结构和对象作用域设计不当,照样吃光内存。
- 初始化集合时预设容量:
new ArrayList(expectedSize)、new HashMap(expectedSize / 0.75f),避免扩容时数组复制和内存碎片 - 长生命周期对象(如Service、Controller)中持有短生命周期数据(如请求上下文缓存),务必在使用后清空引用,例如
cacheMap.remove(key)或tempList.clear(),防止意外延长GC存活周期 - 静态集合(
static List、static Map)是内存泄漏高发区。除非明确需要全局共享且有清理机制,否则改用WeakHashMap或带过期策略的Caffeine缓存
Java免费学习笔记:立即使用
解锁 Java 大师之旅:从入门到精通的终极指南











