- name
- java-optimization
- description
- 执行 Java 代码性能优化,包括 JVM 调优、并发编程、内存管理、缓存策略、数据库优化、集合框架优化等。Invoke when user needs to optimize Java code performance.
- version
- 1.0.0
- last_updated
- 2026-03-11
- author
- 赵辉亮
# Java 性能优化技能
高级 Java 性能优化技术,专注于 JVM 应用性能提升、内存管理、并发处理和系统调优。
## 性能优化策略
### 1. 缓存策略 (Caching)
使用 Spring Cache 或 Caffeine 实现高效缓存:
```java
// ✅ 使用 Caffeine 本地缓存
import com.github.benmanes.caffeine.cache.Cache;
import com.github.benmanes.caffeine.cache.Caffeine;
import java.time.Duration;
public class MaterialService {
private final Cache<String, Material> cache = Caffeine.newBuilder()
.maximumSize(10_000)
.expireAfterWrite(Duration.ofMinutes(10))
.recordStats()
.build();
public Material getMaterial(String code) {
return cache.get(code, key -> repository.findByCode(code));
}
}
```
```java
// ✅ 使用 Spring Cache + Redis
import org.springframework.cache.annotation.Cacheable;
import org.springframework.stereotype.Service;
@Service
public class FormulaService {
@Cacheable(value = "formulas", key = "#id",
condition = "#id != null",
unless = "#result == null")
public Formula getFormula(Long id) {
return formulaRepository.findById(id).orElse(null);
}
}
```
**何时使用缓存:**
- 频繁访问的数据库查询结果
- 计算成本高的数据
- 不经常变化的配置数据
- 第三方 API 调用结果
### 2. 并行处理 (Parallel Processing)
使用 Stream API 和 Fork/Join 框架:
```java
import java.util.stream.Collectors;
// ✅ 并行流处理 CPU 密集型任务
public List<NutritionResult> calculateBatch(List<Material> materials) {
return materials.parallelStream()
.map(this::calculateNutrition)
.collect(Collectors.toList());
}
```
```java
// ✅ 使用 CompletableFuture 异步处理
import java.util.concurrent.CompletableFuture;
import java.util.concurrent.ExecutorService;
import java.util.concurrent.Executors;
public class AsyncCalculator {
private final ExecutorService executor = Executors.newFixedThreadPool(
Runtime.getRuntime().availableProcessors()
);
public CompletableFuture<Double> calculateAsync(Material material) {
return CompletableFuture.supplyAsync(() -> {
return calculateNutrition(material);
}, executor);
}
// ✅ 批量异步处理
public CompletableFuture<List<Result>> batchCalculate(List<Material> materials) {
List<CompletableFuture<Result>> futures = materials.stream()
.map(m -> calculateAsync(m))
.collect(Collectors.toList());
return CompletableFuture.allOf(
futures.toArray(new CompletableFuture[0]))
.thenApply(v -> futures.stream()
.map(CompletableFuture::join)
.collect(Collectors.toList()));
}
}
```
**最佳实践:**
- 并行流适合大数据量和 CPU 密集型操作
- 小数据集使用顺序流(避免线程切换开销)
- 使用 `@Async` 进行异步方法调用
- 合理设置线程池大小
### 3. 内存优化 (Memory Optimization)
#### 避免不必要的对象创建
```java
// ❌ 错误 - 循环内创建对象
for (int i = 0; i < items.size(); i++) {
StringBuilder sb = new StringBuilder();
sb.append(items.get(i));
}
// ✅ 正确 - 循环外创建
StringBuilder sb = new StringBuilder(items.size() * 10);
for (String item : items) {
sb.append(item);
}
```
#### 使用基本类型而非包装类
```java
// ❌ 错误 - 使用包装类
List<Integer> values = new ArrayList<>();
int sum = 0;
for (Integer value : values) {
sum += value; // 自动拆箱
}
// ✅ 正确 - 使用基本类型
int[] values = new int[size];
int sum = 0;
for (int value : values) {
sum += value;
}
```
#### 使用 String.join 替代字符串拼接
```java
// ❌ 错误 - 低效的字符串拼接
String result = "";
for (String item : items) {
result += item + ",";
}
// ✅ 正确 - 使用 String.join
String result = String.join(",", items);
// ✅ 或使用 StringBuilder
StringBuilder sb = new StringBuilder();
for (String item : items) {
sb.append(item).append(",");
}
```
#### 集合初始化时指定容量
```java
// ❌ 错误 - 默认容量可能导致多次扩容
List<String> list = new ArrayList<>();
for (int i = 0; i < 1000; i++) {
list.add(String.valueOf(i));
}
// ✅ 正确 - 预分配容量
List<String> list = new ArrayList<>(1000);
for (int i = 0; i < 1000; i++) {
list.add(String.valueOf(i));
}
```
### 4. 数据库查询优化
#### 避免 N+1 查询问题
```java
// ❌ 错误 - N+1 查询
List<Formula> formulas = formulaRepository.findAll();
for (Formula formula : formulas) {
List<Material> materials = materialRepository.findByFormulaId(formula.getId());
}
// ✅ 正确 - 使用 JOIN FETCH
@Query("SELECT f FROM Formula f LEFT JOIN FETCH f.materials WHERE f.deleted = 0")
List<Formula> findAllWithMaterials();
```
#### 使用批量操作
```java
// ✅ 批量插入/更新
@Transactional
public void batchInsert(List<Item> items) {
int batchSize = 50;
for (int i = 0; i < items.size(); i++) {
entityManager.persist(items.get(i));
if (i % batchSize == 0 && i > 0) {
entityManager.flush();
entityManager.clear();
}
}
}
```
#### 使用投影查询减少数据传输
```java
// ✅ 只查询需要的字段
@Query("SELECT new com.example.dto.FormulaSummary(f.id, f.name, f.totalCost) " +
"FROM Formula f WHERE f.deleted = 0")
List<FormulaSummary> findSummaries();
```
### 5. 并发编程优化
#### 使用线程池
```java
// ✅ 自定义线程池配置
@Configuration
public class ThreadPoolConfig {
@Bean
public Executor taskExecutor() {
ThreadPoolTaskExecutor executor = new ThreadPoolTaskExecutor();
executor.setCorePoolSize(10);
executor.setMaxPoolSize(20);
executor.setQueueCapacity(100);
executor.setThreadNamePrefix("async-executor-");
executor.setRejectedExecutionHandler(new ThreadPoolExecutor.CallerRunsPolicy());
executor.initialize();
return executor;
}
}
```
#### 使用并发容器
```java
// ✅ 线程安全的 Map
ConcurrentHashMap<String, Object> cache = new ConcurrentHashMap<>();
// ✅ 原子操作
AtomicLong counter = new AtomicLong(0);
counter.incrementAndGet();
// ✅ 读写锁
ReadWriteLock lock = new ReentrantReadWriteLock();
lock.readLock().lock();
try {
return cache.get(key);
} finally {
lock.readLock().unlock();
}
```
### 6. JVM 调优参数
#### 堆内存配置
```bash
# 生产环境推荐配置
-Xms4g # 初始堆大小
-Xmx4g # 最大堆大小
-XX:NewRatio=2 # 新生代与老年代比例
-XX:SurvivorRatio=8 # Eden 与 Survivor 比例
-XX:+UseG1GC # 使用 G1 垃圾收集器
-XX:MaxGCPauseMillis=200 # 最大 GC 停顿时间
-XX:+ParallelRefProcEnabled
```
#### GC 日志配置
```bash
# GC 日志记录
-Xloggc:/var/log/gc.log
-XX:+PrintGCDetails
-XX:+PrintGCDateStamps
-XX:+UseGCLogFileRotation
-XX:NumberOfGCLogFiles=10
-XX:GCLogFileSize=100M
```
### 7. Stream API 优化
#### 避免在 Stream 中执行副作用操作
```java
// ❌ 错误 - forEach 有副作用
List<String> result = new ArrayList<>();
list.stream()
.forEach(item -> result.add(transform(item)));
// ✅ 正确 - 使用 map 和 collect
List<String> result = list.stream()
.map(this::transform)
.collect(Collectors.toList());
```
#### 合理使用并行流
```java
// ❌ 错误 - 小数据集使用并行流
List<Integer> smallList = Arrays.asList(1, 2, 3, 4, 5);
smallList.parallelStream().map(...); // 线程切换开销大于收益
// ✅ 正确 - 大数据集或 CPU 密集型任务
if (list.size() > 10000) {
return list.parallelStream().map(...).collect(...);
}
```
### 8. 锁优化
#### 缩小同步范围
```java
// ❌ 错误 - 方法级别同步
public synchronized void process() {
// 非临界区代码
prepare();
// 临界区代码
synchronized(this) {
updateSharedState();
}
}
// ✅ 正确 - 代码块级别同步
public void process() {
prepare(); // 非同步
synchronized(this) {
updateSharedState(); // 仅同步必要部分
}
}
```
#### 使用读写锁优化读多写少场景
```java
// ✅ 使用 ReentrantReadWriteLock
private final ReadWriteLock lock = new ReentrantReadWriteLock();
public Data get(String key) {
lock.readLock().lock();
try {
return cache.get(key);
} finally {
lock.readLock().unlock();
}
}
public void put(String key, Data value) {
lock.writeLock().lock();
try {
cache.put(key, value);
} finally {
lock.writeLock().unlock();
}
}
```
### 9. 集合框架选择
| 场景 | 推荐集合 | 性能特点 |
|------|----------|----------|
| 频繁随机访问 | `ArrayList` | O(1) 访问 |
| 频繁头尾插入删除 | `LinkedList` | O(1) 插入删除 |
| 高频并发读写 | `ConcurrentHashMap` | 分段锁 |
| 有序 Map | `TreeMap` | O(log n) |
| 去重 | `HashSet` | O(1) |
| 固定大小缓存 | `LinkedHashMap` | LRU 支持 |
```java
// ✅ 根据场景选择合适的集合
// 需要快速查找 - 使用 HashMap
Map<Long, RefundOrder> orderMap = new HashMap<>(size);
// 需要保持插入顺序 - 使用 LinkedHashMap
Map<String, Object> orderedCache = new LinkedHashMap<>(16, 0.75f, true);
// 高并发场景 - 使用 ConcurrentHashMap
ConcurrentHashMap<String, Object> concurrentCache = new ConcurrentHashMap<>();
```
## 性能分析工具
### VisualVM 监控
```bash
# 启动 VisualVM
jvisualvm
# 连接到运行中的应用
# 监控:CPU、内存、线程、类加载
# 分析:CPU 热点、内存泄漏
```
### JProfiler 性能分析
```bash
# CPU 分析:识别方法执行热点
# 内存分析:检测内存泄漏
# SQL 分析:优化数据库查询
# 线程分析:检测死锁
```
### Arthas 在线诊断
```bash
# 安装 Arthas
curl -O https://arthas.aliyun.com/arthas-boot.jar
java -jar arthas-boot.jar
# 常用命令
dashboard # 查看系统仪表盘
thread # 查看线程信息
heapdump # 导出堆转储
profiler # CPU 性能分析
trace # 方法调用追踪
watch # 观察方法参数和返回值
```
## 基准测试
### JMH 基准测试
```java
import org.openjdk.jmh.annotations.*;
import java.util.concurrent.TimeUnit;
@State(Scope.Thread)
@BenchmarkMode(Mode.AverageTime)
@OutputTimeUnit(TimeUnit.NANOSECONDS)
public class BenchmarkTest {
@Param({"100", "1000", "10000"})
public int size;
private List<String> dataList;
@Setup
public void setup() {
dataList = IntStream.range(0, size)
.mapToObj(String::valueOf)
.collect(Collectors.toList());
}
@Benchmark
public String testStringBuilder() {
StringBuilder sb = new StringBuilder();
for (String s : dataList) {
sb.append(s);
}
return sb.toString();
}
@Benchmark
public String testStringJoiner() {
StringJoiner joiner = new StringJoiner("");
for (String s : dataList) {
joiner.add(s);
}
return joiner.toString();
}
}
```
## 常见性能反模式
### ❌ 在循环中执行数据库查询
```java
// 错误示例
for (Order order : orders) {
User user = userRepository.findById(order.getUserId());
}
// 正确做法
List<Long> userIds = orders.stream()
.map(Order::getUserId)
.collect(Collectors.toList());
List<User> users = userRepository.findAllById(userIds);
```
### ❌ 滥用同步
```java
// 错误示例 - 过度同步
public synchronized void method() {
// 只有部分代码需要同步
}
// 正确做法 - 缩小同步范围
View on GitHub