Java代码优化技巧:循环展开与内存访问优化
循环展开优化
循环展开(Loop Unrolling)是一种减少循环控制开销的技术,通过减少循环次数、增加每次迭代的工作量来提升性能。适用于循环体简单且迭代次数固定的场景。
示例代码:未展开的循环
for (int i = 0; i < 100; i++) { sum += array[i]; }展开后的循环(4次展开)
for (int i = 0; i < 100; i += 4) { sum += array[i]; sum += array[i+1]; sum += array[i+2]; sum += array[i+3]; }优化效果
- 减少分支预测失败次数
- 降低循环索引计算开销
- 可能触发编译器自动向量化
注意事项
- 展开次数需适中(通常2-8次)
- 剩余迭代需单独处理(若总数非展开倍数)
- 可能增加代码体积,需权衡缓存影响
内存访问优化
内存访问模式对性能影响显著,优化目标是提升缓存命中率、减少内存延迟。
1. 顺序访问优于随机访问
- 顺序访问可触发预取机制
- 示例:优先遍历一维数组而非链表
2. 空间局部性优化
// 低效:列优先访问二维数组 for (int col = 0; col < N; col++) { for (int row = 0; row < M; row++) { sum += matrix[row][col]; } } // 高效:行优先访问(与内存布局一致) for (int row = 0; row < M; row++) { for (int col = 0; col < N; col++) { sum += matrix[row][col]; } }3. 数据对齐
- 对象大小尽量为2^n字节
- 使用
@Contended注解避免伪共享(Java 8+) - modelscope.cn/learn/71489
modelscope.cn/learn/71488
modelscope.cn/learn/71485
modelscope.cn/learn/71484
modelscope.cn/learn/71482
modelscope.cn/learn/71480
modelscope.cn/learn/71478
modelscope.cn/learn/71476
modelscope.cn/learn/71474
modelscope.cn/learn/71472
modelscope.cn/learn/71470
modelscope.cn/learn/71469
modelscope.cn/learn/71466
modelscope.cn/learn/71465
modelscope.cn/learn/71462
4. 对象复用
- 避免频繁创建小对象
- 使用对象池或线程局部变量
复合优化策略
循环展开+内存预取
final int CHUNK = 4; for (int i = 0; i < array.length; i += CHUNK) { // 手动预取下个块 if (i + CHUNK < array.length) { Prefetch.access(array, i + CHUNK); } // 展开处理当前块 sum += array[i]; sum += array[i+1]; sum += array[i+2]; sum += array[i+3]; }工具辅助
- 使用JMH进行微观基准测试
- 通过JITWatch分析热点代码
- 检查
-XX:+PrintAssembly输出的汇编指令
注意事项
- 优先使用
System.arraycopy()而非手动循环拷贝 - 对于边界检查,JVM会优化简单循环的边界检查
- 避免在循环内调用
length方法(缓存到局部变量) - 考虑使用
Arrays.fill()等内置优化方法
