Java应用性能优化实战
在Java应用开发中,性能优化是一个永恒的话题。本文将分享一些实用的Java性能优化技巧和最佳实践。
JVM调优
内存分配
合理的JVM内存配置对应用性能至关重要:
# JVM内存配置参数
java -Xms4g -Xmx4g -XX:MetaspaceSize=256m -XX:MaxMetaspaceSize=256m -jar app.jar
主要参数说明:
-Xms: 初始堆大小-Xmx: 最大堆大小-XX:MetaspaceSize: 元空间初始大小-XX:MaxMetaspaceSize: 元空间最大大小
GC优化
选择合适的垃圾收集器:
# G1垃圾收集器配置
-XX:+UseG1GC # 使用G1垃圾收集器
-XX:MaxGCPauseMillis=200 # 最大GC停顿时间
代码层面优化
1. 合理使用集合
// 集合类的选择与优化
// ArrayList vs LinkedList的选择
List<String> list = new ArrayList<>(); // 随机访问优先,内存连续,适合读多写少
List<String> queue = new LinkedList<>(); // 频繁插入删除,内存不连续,适合写多读少
// HashMap初始化优化
Map<String, Object> map = new HashMap<>(16, 0.75f); // 指定初始容量和负载因子,减少扩容
2. 字符串处理
// 字符串拼接优化
StringBuilder sb = new StringBuilder(); // 可变字符串,线程不安全但性能好
for (String str : list) {
sb.append(str); // 避免在循环中使用+拼接字符串
}
String result = sb.toString();
// 字符串常量池优化
String str1 = "hello"; // 直接进入常量池,节省内存
String str2 = new String("hello"); // 在堆内存创建对象,性能较差
3. 线程池优化
// 线程池配置
ThreadPoolExecutor executor = new ThreadPoolExecutor(
10, // 核心线程数:常驻线程数量
20, // 最大线程数:最大并发数
60L, // 空闲线程存活时间
TimeUnit.SECONDS, // 时间单位
new ArrayBlockingQueue<>(100), // 工作队列:存储等待执行的任务
new ThreadPoolExecutor.CallerRunsPolicy() // 拒绝策略:任务过多时的处理方式
);
数据库优化
1. 连接池配置
# 数据库连接池配置
spring:
datasource:
hikari:
maximum-pool-size: 10 # 最大连接数
minimum-idle: 5 # 最小空闲连接
idle-timeout: 300000 # 空闲连接超时时间
connection-timeout: 20000 # 连接超时时间
max-lifetime: 1200000 # 连接最大生命周期
2. SQL优化
-- 索引优化
CREATE INDEX idx_user_name ON users(name); -- 创建索引提高查询效率
-- 查询优化
SELECT * FROM users
WHERE name = 'fashioncool'
AND age > 20; -- 使用索引字段作为查询条件
缓存策略
Redis缓存配置
// 使用缓存注解
@Cacheable(value = "users", key = "#id") // 配置缓存key和缓存名称
public User getUser(Long id) {
// 从数据库查询用户信息
return userRepository.findById(id)
.orElseThrow(() -> new UserNotFoundException(id));
}
监控与分析
使用JProfiler进行性能分析
- CPU热点分析
- 内存泄漏检测
- 线程分析
- SQL执行分析
实践建议
- 先监控,后优化
- 建立性能基准
- 优化最影响性能的部分
- 持续监控和调优
性能优化是一个持续的过程,需要我们在实践中不断积累经验。后续我会继续分享更多性能优化的实战经验。