作为深耕Java领域15年的资深架构师,我见证了太多因性能问题导致的系统崩溃。今天我将分享10个经过千锤百炼的性能优化技巧,让你的程序性能实现质的飞跃!
1. 字符串拼接:用告别“+”号
错误示范:
String result = "";
for (int i = 0; i < 10000; i++) {
result += "data" + i; // 每次循环都创建新对象!
}
优化方案:
StringBuilder sb = new StringBuilder(50000); // 预设容量
for (int i = 0; i < 10000; i++) {
sb.append("data").append(i);
}
String result = sb.toString();
效果: 万次拼接性能提升50倍!
2. 集合初始化:给一个合适的容量
错误示范:
Map map = new HashMap(); // 默认16,很快需要扩容
for (int i = 0; i < 1000; i++) {
map.put("key" + i, "value" + i);
}
优化方案:
// 预计算容量:元素数 / 0.75 + 1
Map map = new HashMap(1334);
for (int i = 0; i < 1000; i++) {
map.put("key" + i, "value" + i);
}
效果: 避免多次扩容,万次put性能提升3倍!
3. 正则表达式:预编译对象
错误示范:
// 每次调用都重新编译
for (String input : inputList) {
if (input.matches("^\d{4}-\d{2}-\d{2}#34;)) { // 每次都编译!
// ...
}
}
优化方案:
private static final Pattern DATE_PATTERN =
Pattern.compile("^\d{4}-\d{2}-\d{2}#34;);
for (String input : inputList) {
if (DATE_PATTERN.matcher(input).matches()) { // 复用已编译对象
// ...
}
}
效果: 万次匹配性能提升10倍!
4. 自动装箱:警惕隐式对象创建
错误示范:
Long sum = 0L; // 自动装箱为Long对象
for (long i = 0; i < Integer.MAX_VALUE; i++) {
sum += i; // 每次循环都创建新Long对象!
}
优化方案:
long sum = 0L; // 使用基本类型
for (long i = 0; i < Integer.MAX_VALUE; i++) {
sum += i; // 直接操作基本类型
}
效果: 亿次累加内存减少95%!
5. 数据库连接:用好连接池参数
错误配置:
// HikariCP默认配置可能不适用高并发
HikariConfig config = new HikariConfig();
config.setMaximumPoolSize(10); // 并发高时排队等待
优化配置:
HikariConfig config = new HikariConfig();
config.setMaximumPoolSize(50); // 根据业务调整
config.setMinimumIdle(10); // 保持最小连接
config.setConnectionTimeout(30000);
config.setIdleTimeout(600000);
config.setMaxLifetime(1800000);
config.setConnectionTestQuery("SELECT 1");
效果: 高并发下数据库响应时间降低80%!
6. 日志输出:用占位符替代字符串拼接
错误示范:
log.debug("User " + userId + " accessed " + resource); // 即使不输出也执行拼接
优化方案:
log.debug("User {} accessed {}", userId, resource); // 延迟拼接
进阶优化:
if (log.isDebugEnabled()) { // 预先判断级别
log.debug("User {} accessed {}", userId, resource);
}
效果: 日志模块性能提升5倍!
7. 反射调用:缓存对象
错误示范:
// 每次调用都获取Method
for (int i = 0; i < 10000; i++) {
Method method = obj.getClass().getMethod("process");
method.invoke(obj);
}
优化方案:
// 缓存Method对象
Method method = obj.getClass().getMethod("process");
for (int i = 0; i < 10000; i++) {
method.invoke(obj);
}
最佳实践:
// 使用预编译的字节码增强(如CGLIB)
Enhancer enhancer = new Enhancer();
enhancer.setSuperclass(Service.class);
enhancer.setCallback(new MethodInterceptor() {
public Object intercept(Object obj, Method method, Object[] args, MethodProxy proxy) {
return proxy.invokeSuper(obj, args); // 直接调用,无反射开销
}
});
效果: 反射调用性能提升100倍!
8. API:合理选择并行流
错误示范:
List list = new ArrayList();
// 小数据量使用并行流反而更慢
list.parallelStream().map(x -> x * 2).collect(Collectors.toList());
优化方案:
List list = new ArrayList();
// 大数据量(>10000)才用并行流
if (list.size() > 10000) {
list.parallelStream().map(x -> x * 2).collect(Collectors.toList());
} else {
list.stream().map(x -> x * 2).collect(Collectors.toList());
}
效果: 大数据处理性能提升3-8倍!
9. 对象复用:避免频繁创建短命对象
错误示范:
public void processRequest(HttpRequest request) {
SimpleDateFormat sdf = new SimpleDateFormat("yyyy-MM-dd"); // 每次调用都创建
String date = sdf.format(new Date());
// ...
}
优化方案:
// 使用ThreadLocal避免线程安全问题
private static final ThreadLocal DATE_FORMATTER =
ThreadLocal.withInitial(() -> new SimpleDateFormat("yyyy-MM-dd"));
public void processRequest(HttpRequest request) {
String date = DATE_FORMATTER.get().format(new Date()); // 复用对象
// ...
}
替代方案:
// Java 8推荐使用DateTimeFormatter
private static final DateTimeFormatter FORMATTER =
DateTimeFormatter.ofPattern("yyyy-MM-dd");
String date = LocalDate.now().format(FORMATTER); // 线程安全且高效
效果: 高频调用下性能提升20倍!
10. JVM参数调优:针对性设置GC策略
通用配置:
# 生产环境推荐配置
-Xms4g -Xmx4g # 堆内存固定,避免动态调整
-XX:+UseG1GC # G1垃圾收集器
-XX:MaxGCPauseMillis=200 # 目标暂停时间
-XX:InitiatingHeapOccupancyPercent=35 # 触发GC的堆占用比
-XX:+UseStringDeduplication # 字符串去重
-XX:+PrintGCDetails -Xloggc:/path/to/gc.log # GC日志
内存分析工具使用:
// 添加JVM参数获取内存dump
-XX:+HeapDumpOnOutOfMemoryError
-XX:HeapDumpPath=/path/to/dump.hprof
// 使用jcmd分析
jcmd GC.heap_dump /path/to/dump.hprof
效果: 合理配置可减少Full GC 90%以上!
总结
性能优化不是炫技,而是基于数据和场景的理性选择。记住这三点:
测量优先:用JMH做基准测试,用分析瓶颈权衡利弊:空间换时间,可读性换性能渐进优化:80%的性能问题来自20%的代码
最后送上我的调优箴言:“不要过早优化,但要时时关注性能指标”。优化之路永无止境,但掌握这些核心技巧,你已能解决90%的常见性能问题!
立即行动,用、jmap、等工具分析你的应用,从今天开始写出高性能的Java代码!




发表回复