第495集性能调优
|字数总计:3.8k|阅读时长:16分钟|阅读量:
性能调优
1. 概述
1.1 性能调优的重要性
性能调优是系统开发中的关键环节,能够提升系统响应速度、降低资源消耗、提高用户体验,是架构师和高级开发者的必备技能。
本文内容:
- 性能调优原则:调优的基本原则和方法
- JVM调优:堆内存、GC、JIT等调优
- 代码优化:算法优化、数据结构优化
- 数据库优化:SQL优化、索引优化
- 缓存优化:缓存策略和优化
- 并发优化:多线程性能优化
- 监控诊断:性能监控和问题诊断
1.2 本文内容结构
本文将从以下几个方面深入探讨性能调优:
- 性能调优原则:调优的基本原则
- JVM调优:JVM参数调优
- 代码优化:代码层面优化
- 数据库优化:数据库性能优化
- 缓存优化:缓存策略优化
- 并发优化:并发性能优化
- 监控诊断:性能监控和诊断
2. 性能调优原则
2.1 调优原则
2.1.1 基本原则
性能调优原则:
- 先测量,后优化:先找出性能瓶颈,再优化
- 80/20原则:优化20%的关键代码,解决80%的性能问题
- 避免过早优化:不要过早优化,先保证功能正确
- 权衡取舍:性能与可维护性、可读性的平衡
性能调优流程:
1 2 3 4 5 6 7 8 9 10 11 12 13
| 1. 性能测试 ↓ 2. 性能分析 ↓ 3. 找出瓶颈 ↓ 4. 制定优化方案 ↓ 5. 实施优化 ↓ 6. 验证效果 ↓ 7. 持续监控
|
2.2 性能指标
2.2.1 关键指标
性能指标:
- 响应时间:请求处理时间
- 吞吐量:单位时间处理请求数
- 并发数:同时处理的请求数
- 资源利用率:CPU、内存、IO使用率
- 错误率:请求失败率
3. JVM调优
3.1 堆内存调优
3.1.1 堆内存参数
堆内存调优参数:
1 2 3 4 5 6 7 8 9 10
| -Xms2g -Xmx4g -Xmn1g
-XX:NewRatio=2
-XX:SurvivorRatio=8
|
调优建议:
- -Xms和-Xmx设置相同:避免动态扩容,减少GC
- 新生代大小:通常为堆的1/3到1/4
- 根据应用特点调整:短生命周期对象多,增大新生代
3.2 GC调优
3.2.1 GC参数调优
G1 GC调优:
1 2 3 4 5 6
| -XX:+UseG1GC -XX:MaxGCPauseMillis=200 -XX:G1HeapRegionSize=16m -XX:InitiatingHeapOccupancyPercent=45 -XX:ConcGCThreads=4
|
Parallel GC调优:
1 2 3 4 5
| -XX:+UseParallelGC -XX:ParallelGCThreads=4 -XX:MaxGCPauseMillis=200 -XX:GCTimeRatio=19
|
CMS GC调优:
1 2 3 4 5
| -XX:+UseConcMarkSweepGC -XX:CMSInitiatingOccupancyFraction=70 -XX:+UseCMSInitiatingOccupancyOnly -XX:+CMSParallelRemarkEnabled
|
3.3 JIT调优
3.3.1 JIT编译参数
JIT编译调优:
1 2 3 4 5 6
| -XX:+TieredCompilation -XX:CompileThreshold=10000 -XX:+PrintCompilation -XX:+UnlockDiagnosticVMOptions -XX:+PrintInlining
|
3.4 方法区调优
3.4.1 元空间调优
元空间调优:
1 2 3 4 5 6 7
| -XX:MetaspaceSize=256m -XX:MaxMetaspaceSize=512m
-XX:PermSize=256m -XX:MaxPermSize=512m
|
4. 代码优化
4.1 算法优化
4.1.1 算法选择
算法优化示例:
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37
| public class AlgorithmOptimization { public int findMaxBad(int[] array) { int max = Integer.MIN_VALUE; for (int i = 0; i < array.length; i++) { for (int j = 0; j < array.length; j++) { if (array[j] > max) { max = array[j]; } } } return max; } public int findMaxGood(int[] array) { int max = Integer.MIN_VALUE; for (int value : array) { if (value > max) { max = value; } } return max; } public void sortExample(int[] array) { if (array.length < 10) { insertionSort(array); } else { quickSort(array); } } }
|
4.2 数据结构优化
4.2.1 数据结构选择
数据结构优化:
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44
| import java.util.*;
public class DataStructureOptimization { public void collectionOptimization() { Map<String, String> map = new HashMap<>(); Map<String, String> sortedMap = new TreeMap<>(); Map<String, String> concurrentMap = new ConcurrentHashMap<>(); List<String> list = new CopyOnWriteArrayList<>(); } public void capacityOptimization() { List<String> list1 = new ArrayList<>(); List<String> list2 = new ArrayList<>(1000); Map<String, String> map = new HashMap<>(1000); } public void primitiveOptimization() { Integer sum = 0; for (int i = 0; i < 1000000; i++) { sum += i; } int sum2 = 0; for (int i = 0; i < 1000000; i++) { sum2 += i; } } }
|
4.3 字符串优化
4.3.1 字符串处理优化
字符串优化:
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34
| public class StringOptimization { public void stringConcatenation() { String result = ""; for (int i = 0; i < 1000; i++) { result += i; } StringBuilder sb = new StringBuilder(); for (int i = 0; i < 1000; i++) { sb.append(i); } String result2 = sb.toString(); } public void stringBuilderCapacity() { StringBuilder sb = new StringBuilder(1000); } public void stringPool() { String str1 = "Hello"; String str2 = "Hello"; String str3 = new String("Hello"); } }
|
4.4 循环优化
4.4.1 循环性能优化
循环优化:
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32
| public class LoopOptimization { public void reduceMethodCalls(int[] array) { for (int i = 0; i < array.length; i++) { } int len = array.length; for (int i = 0; i < len; i++) { } } public void enhancedForLoop(List<String> list) { for (String item : list) { } } public void loopUnrolling() { for (int i = 0; i < 4; i++) { } } }
|
5. 数据库优化
5.1 SQL优化
5.1.1 SQL语句优化
SQL优化:
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32
|
SELECT * FROM users WHERE id = 1;
SELECT id, name, email FROM users WHERE id = 1;
CREATE INDEX idx_user_email ON users(email);
SELECT * FROM users WHERE email = 'test@example.com';
SELECT * FROM users WHERE YEAR(create_time) = 2024;
SELECT * FROM users WHERE create_time >= '2024-01-01' AND create_time < '2025-01-01';
SELECT * FROM users LIMIT 10;
SELECT * FROM orders WHERE user_id IN (SELECT id FROM users WHERE status = 1);
SELECT o.* FROM orders o JOIN users u ON o.user_id = u.id WHERE u.status = 1;
|
5.2 索引优化
5.2.1 索引策略
索引优化:
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20
| CREATE INDEX idx_user_email ON users(email); CREATE INDEX idx_order_user_date ON orders(user_id, create_date);
SELECT * FROM users WHERE email = 'test@example.com'; SELECT * FROM users WHERE email = 'test@example.com' AND status = 1;
SELECT * FROM users WHERE status = 1;
CREATE INDEX idx_user_cover ON users(id, name, email); SELECT id, name, email FROM users WHERE id = 1;
|
5.3 连接池优化
5.3.1 数据库连接池
连接池优化:
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22
| @Configuration public class DataSourceConfig { @Bean public DataSource dataSource() { HikariConfig config = new HikariConfig(); config.setJdbcUrl("jdbc:mysql://localhost:3306/test"); config.setUsername("root"); config.setPassword("password"); config.setMaximumPoolSize(20); config.setMinimumIdle(5); config.setConnectionTimeout(30000); config.setIdleTimeout(600000); config.setMaxLifetime(1800000); config.setLeakDetectionThreshold(60000); return new HikariDataSource(config); } }
|
6. 缓存优化
6.1 缓存策略
6.1.1 缓存策略选择
缓存策略:
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35
| public class CacheStrategy { public User getUser(Long id) { User user = cache.get("user:" + id); if (user != null) { return user; } user = userRepository.findById(id); if (user != null) { cache.put("user:" + id, user, 3600); } return user; } public void updateUser(User user) { userRepository.update(user); cache.put("user:" + user.getId(), user); } public void updateUserWriteBack(User user) { cache.put("user:" + user.getId(), user); asyncUpdateDatabase(user); } }
|
6.2 多级缓存
6.2.1 缓存层次
多级缓存:
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39
| public class MultiLevelCache { private final Cache<String, Object> l1Cache = Caffeine.newBuilder() .maximumSize(10000) .expireAfterWrite(5, TimeUnit.MINUTES) .build(); @Autowired private RedisTemplate<String, Object> redisTemplate; public Object get(String key) { Object value = l1Cache.getIfPresent(key); if (value != null) { return value; } value = redisTemplate.opsForValue().get(key); if (value != null) { l1Cache.put(key, value); return value; } value = loadFromDatabase(key); if (value != null) { redisTemplate.opsForValue().set(key, value, 1, TimeUnit.HOURS); l1Cache.put(key, value); } return value; } }
|
6.3 缓存预热
6.3.1 预热策略
缓存预热:
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21
| @Component public class CacheWarmup { @Autowired private UserService userService; @PostConstruct public void warmup() { List<Long> hotUserIds = getHotUserIds(); for (Long userId : hotUserIds) { userService.getUser(userId); } } @Scheduled(cron = "0 0 6 * * ?") public void scheduledWarmup() { warmup(); } }
|
7. 并发优化
7.1 线程池优化
7.1.1 线程池参数
线程池优化:
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29
| public class ThreadPoolOptimization { public ThreadPoolExecutor createOptimalThreadPool() { int corePoolSize = Runtime.getRuntime().availableProcessors(); int maximumPoolSize = corePoolSize * 2; return new ThreadPoolExecutor( corePoolSize, maximumPoolSize, 60L, TimeUnit.SECONDS, new LinkedBlockingQueue<>(1000), new ThreadFactory() { private int count = 0; @Override public Thread newThread(Runnable r) { Thread thread = new Thread(r); thread.setName("Worker-" + (++count)); return thread; } }, new ThreadPoolExecutor.CallerRunsPolicy() ); } }
|
7.2 锁优化
7.2.1 减少锁竞争
锁优化:
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53
| public class LockOptimization { private final Map<String, Object> map1 = new HashMap<>(); private final Object lock1 = new Object(); public void updateBad(String key, Object value) { synchronized (lock1) { map1.put(key, value); doSomethingElse(); } } public void updateGood(String key, Object value) { synchronized (lock1) { map1.put(key, value); } doSomethingElse(); } private final Map<String, Object>[] segments = new Map[16]; private final Object[] locks = new Object[16]; { for (int i = 0; i < 16; i++) { segments[i] = new HashMap<>(); locks[i] = new Object(); } } public void put(String key, Object value) { int segment = key.hashCode() % 16; synchronized (locks[segment]) { segments[segment].put(key, value); } } private final ReadWriteLock readWriteLock = new ReentrantReadWriteLock(); public Object read(String key) { readWriteLock.readLock().lock(); try { return map1.get(key); } finally { readWriteLock.readLock().unlock(); } } }
|
7.3 无锁编程
7.3.1 CAS操作
无锁编程:
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25
| import java.util.concurrent.atomic.*;
public class LockFreeProgramming { private final AtomicInteger count = new AtomicInteger(0); public void increment() { count.incrementAndGet(); } public void updateWithCAS(int expected, int newValue) { while (!count.compareAndSet(expected, newValue)) { expected = count.get(); } } private final LongAdder longAdder = new LongAdder(); public void add() { longAdder.increment(); } }
|
8. 监控诊断
8.1 性能监控
8.1.1 监控工具
性能监控工具:
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42
| public class PerformanceMonitor { public void monitorExample() { MemoryMXBean memoryBean = ManagementFactory.getMemoryMXBean(); MemoryUsage heapUsage = memoryBean.getHeapMemoryUsage(); System.out.println("Heap used: " + heapUsage.getUsed()); System.out.println("Heap max: " + heapUsage.getMax()); ThreadMXBean threadBean = ManagementFactory.getThreadMXBean(); int threadCount = threadBean.getThreadCount(); System.out.println("Thread count: " + threadCount); } }
@Component public class MetricsExample { private final MeterRegistry meterRegistry; private final Counter requestCounter; private final Timer requestTimer; public MetricsExample(MeterRegistry meterRegistry) { this.meterRegistry = meterRegistry; this.requestCounter = Counter.builder("requests.total") .description("Total requests") .register(meterRegistry); this.requestTimer = Timer.builder("requests.duration") .description("Request duration") .register(meterRegistry); } public void handleRequest() { requestCounter.increment(); requestTimer.record(() -> { }); } }
|
8.2 性能分析
8.2.1 性能分析工具
性能分析工具:
1 2 3 4 5 6 7 8 9 10 11 12 13 14
| jstat -gc <pid> 1000 10
jmap -dump:format=b,file=heap.hprof <pid>
jstack <pid> > thread.dump
jvisualvm
java -jar arthas-boot.jar
|
8.3 性能测试
8.3.1 压力测试
性能测试:
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26
| @BenchmarkMode(Mode.AverageTime) @OutputTimeUnit(TimeUnit.NANOSECONDS) @State(Scope.Benchmark) public class PerformanceBenchmark { private List<String> list; @Setup public void setup() { list = new ArrayList<>(); for (int i = 0; i < 1000; i++) { list.add("Item " + i); } } @Benchmark public void testMethod1() { } @Benchmark public void testMethod2() { } }
|
9. 实战案例
9.1 性能优化案例
9.1.1 案例:接口响应慢
问题:接口响应时间从50ms增加到500ms。
分析步骤:
- 性能测试:使用压测工具测试接口
- 性能分析:使用jstack、jmap分析
- 找出瓶颈:发现数据库查询慢
- 优化方案:
优化效果:
- 响应时间:500ms → 80ms
- 吞吐量:提升5倍
9.2 GC优化案例
9.2.1 案例:频繁Full GC
问题:系统频繁Full GC,响应变慢。
分析:
- GC日志显示:Full GC频率高
- 堆内存使用率高
- 对象存活时间长
优化方案:
1 2 3 4 5 6 7 8 9
| -Xms2g -Xmx2g -XX:+UseParallelGC
-Xms4g -Xmx4g -Xmn2g -XX:+UseG1GC -XX:MaxGCPauseMillis=200
|
优化效果:
- Full GC频率:降低80%
- 平均响应时间:降低30%
10. 总结
10.1 核心要点
- 先测量,后优化:找出瓶颈再优化
- JVM调优:合理设置堆内存和GC参数
- 代码优化:算法、数据结构、字符串优化
- 数据库优化:SQL优化、索引优化、连接池优化
- 缓存优化:合理使用缓存,多级缓存
- 并发优化:线程池、锁优化、无锁编程
10.2 关键理解
- 性能是权衡:性能与可维护性的平衡
- 监控重要:完善的监控是调优的基础
- 持续优化:性能调优是持续的过程
- 避免过度优化:不要过早优化
10.3 最佳实践
- 建立性能基线:记录优化前的性能指标
- 逐步优化:一次优化一个方面
- 验证效果:每次优化后验证效果
- 持续监控:建立完善的监控体系
相关文章: