Java学习第20天 - 性能优化与监控

学习目标

  • 掌握Java性能优化的核心技巧
  • 学习JVM调优和内存管理
  • 掌握性能监控工具的使用
  • 了解Spring Boot性能优化最佳实践
  • 学习数据库性能优化技巧

一、Java性能优化基础

1. 代码层面优化

java 复制代码
// 1. 字符串优化
public class StringOptimization {
    // ❌ 低效:频繁字符串拼接
    public String inefficientConcat(String[] words) {
        String result = "";
        for (String word : words) {
            result += word + " ";  // 每次都创建新String对象
        }
        return result;
    }
    
    // ✅ 高效:使用StringBuilder
    public String efficientConcat(String[] words) {
        StringBuilder sb = new StringBuilder();
        for (String word : words) {
            sb.append(word).append(" ");
        }
        return sb.toString();
    }
    
    // ✅ 更高效:预分配容量
    public String optimizedConcat(String[] words) {
        StringBuilder sb = new StringBuilder(words.length * 10); // 预分配容量
        for (String word : words) {
            sb.append(word).append(" ");
        }
        return sb.toString();
    }
}

// 2. 集合优化
public class CollectionOptimization {
    // ❌ 低效:频繁扩容
    public List<String> inefficientList() {
        List<String> list = new ArrayList<>(); // 默认容量10
        for (int i = 0; i < 1000; i++) {
            list.add("item" + i); // 可能触发多次扩容
        }
        return list;
    }
    
    // ✅ 高效:预分配容量
    public List<String> efficientList() {
        List<String> list = new ArrayList<>(1000); // 预分配容量
        for (int i = 0; i < 1000; i++) {
            list.add("item" + i);
        }
        return list;
    }
    
    // 3. 选择合适的集合类型
    public void chooseRightCollection() {
        // 频繁随机访问 - 使用ArrayList
        List<String> randomAccess = new ArrayList<>();
        
        // 频繁插入删除 - 使用LinkedList
        List<String> frequentModification = new LinkedList<>();
        
        // 去重 - 使用HashSet
        Set<String> uniqueItems = new HashSet<>();
        
        // 有序去重 - 使用TreeSet
        Set<String> sortedUnique = new TreeSet<>();
        
        // 键值对 - 使用HashMap
        Map<String, String> keyValue = new HashMap<>();
    }
}

// 3. 循环优化
public class LoopOptimization {
    // ❌ 低效:在循环中调用方法
    public int inefficientLoop(List<String> list) {
        int sum = 0;
        for (int i = 0; i < list.size(); i++) { // 每次循环都调用size()
            sum += list.get(i).length();
        }
        return sum;
    }
    
    // ✅ 高效:缓存方法调用结果
    public int efficientLoop(List<String> list) {
        int sum = 0;
        int size = list.size(); // 缓存size()结果
        for (int i = 0; i < size; i++) {
            sum += list.get(i).length();
        }
        return sum;
    }
    
    // ✅ 更高效:使用增强for循环
    public int enhancedForLoop(List<String> list) {
        int sum = 0;
        for (String item : list) {
            sum += item.length();
        }
        return sum;
    }
}

2. 对象创建优化

java 复制代码
// 对象池模式
public class ObjectPool<T> {
    private final Queue<T> pool;
    private final Supplier<T> factory;
    private final int maxSize;
    
    public ObjectPool(Supplier<T> factory, int maxSize) {
        this.factory = factory;
        this.maxSize = maxSize;
        this.pool = new ConcurrentLinkedQueue<>();
    }
    
    public T borrow() {
        T object = pool.poll();
        if (object == null) {
            object = factory.get();
        }
        return object;
    }
    
    public void returnObject(T object) {
        if (pool.size() < maxSize) {
            pool.offer(object);
        }
    }
}

// 使用示例
public class StringBufferPool {
    private static final ObjectPool<StringBuilder> POOL = 
        new ObjectPool<>(StringBuilder::new, 10);
    
    public String processString(List<String> items) {
        StringBuilder sb = POOL.borrow();
        try {
            for (String item : items) {
                sb.append(item).append(" ");
            }
            return sb.toString();
        } finally {
            sb.setLength(0); // 清空内容
            POOL.returnObject(sb);
        }
    }
}

二、JVM调优与内存管理

1. 内存区域优化

java 复制代码
// 内存使用监控
public class MemoryMonitor {
    private static final MemoryMXBean memoryBean = ManagementFactory.getMemoryMXBean();
    
    public void printMemoryUsage() {
        MemoryUsage heapUsage = memoryBean.getHeapMemoryUsage();
        MemoryUsage nonHeapUsage = memoryBean.getNonHeapMemoryUsage();
        
        System.out.println("=== 堆内存使用情况 ===");
        System.out.println("已使用: " + formatBytes(heapUsage.getUsed()));
        System.out.println("已提交: " + formatBytes(heapUsage.getCommitted()));
        System.out.println("最大: " + formatBytes(heapUsage.getMax()));
        System.out.println("使用率: " + getUsagePercentage(heapUsage) + "%");
        
        System.out.println("\n=== 非堆内存使用情况 ===");
        System.out.println("已使用: " + formatBytes(nonHeapUsage.getUsed()));
        System.out.println("已提交: " + formatBytes(nonHeapUsage.getCommitted()));
        System.out.println("最大: " + formatBytes(nonHeapUsage.getMax()));
    }
    
    private String formatBytes(long bytes) {
        if (bytes < 1024) return bytes + " B";
        if (bytes < 1024 * 1024) return String.format("%.2f KB", bytes / 1024.0);
        if (bytes < 1024 * 1024 * 1024) return String.format("%.2f MB", bytes / (1024.0 * 1024));
        return String.format("%.2f GB", bytes / (1024.0 * 1024 * 1024));
    }
    
    private double getUsagePercentage(MemoryUsage usage) {
        return (double) usage.getUsed() / usage.getMax() * 100;
    }
}

// 垃圾回收监控
public class GCMonitor {
    private static final List<GarbageCollectorMXBean> gcBeans = 
        ManagementFactory.getGarbageCollectorMXBeans();
    
    public void printGCInfo() {
        System.out.println("=== 垃圾回收器信息 ===");
        for (GarbageCollectorMXBean gcBean : gcBeans) {
            System.out.println("名称: " + gcBean.getName());
            System.out.println("收集次数: " + gcBean.getCollectionCount());
            System.out.println("收集时间: " + gcBean.getCollectionTime() + " ms");
            System.out.println("内存池: " + Arrays.toString(gcBean.getMemoryPoolNames()));
            System.out.println("---");
        }
    }
}

2. JVM参数调优

java 复制代码
// JVM参数配置示例
public class JVMConfigExample {
    /*
     * 推荐的JVM参数配置:
     * 
     * 1. 堆内存设置
     * -Xms2g -Xmx2g                    # 初始堆大小和最大堆大小
     * -XX:NewRatio=2                   # 新生代与老年代比例 1:2
     * -XX:SurvivorRatio=8              # Eden与Survivor比例 8:1:1
     * 
     * 2. 垃圾回收器选择
     * -XX:+UseG1GC                     # 使用G1垃圾回收器
     * -XX:MaxGCPauseMillis=200         # 最大GC暂停时间
     * -XX:G1HeapRegionSize=16m         # G1区域大小
     * 
     * 3. GC日志
     * -XX:+PrintGC                     # 打印GC信息
     * -XX:+PrintGCDetails              # 打印GC详细信息
     * -XX:+PrintGCTimeStamps           # 打印GC时间戳
     * -Xloggc:gc.log                   # GC日志文件
     * 
     * 4. 其他优化
     * -XX:+UseStringDeduplication      # 字符串去重
     * -XX:+OptimizeStringConcat        # 优化字符串拼接
     * -XX:+UseCompressedOops           # 压缩指针
     */
}

三、Spring Boot性能优化

1. 应用配置优化

java 复制代码
// 1. 数据库连接池优化
@Configuration
public class DatabaseConfig {
    
    @Bean
    @ConfigurationProperties("spring.datasource.hikari")
    public HikariConfig hikariConfig() {
        HikariConfig config = new HikariConfig();
        // 连接池大小
        config.setMaximumPoolSize(20);
        config.setMinimumIdle(5);
        // 连接超时
        config.setConnectionTimeout(30000);
        config.setIdleTimeout(600000);
        // 连接生命周期
        config.setMaxLifetime(1800000);
        // 连接测试
        config.setConnectionTestQuery("SELECT 1");
        config.setValidationTimeout(5000);
        return config;
    }
    
    @Bean
    public DataSource dataSource() {
        return new HikariDataSource(hikariConfig());
    }
}

// 2. 缓存配置优化
@Configuration
@EnableCaching
public class CacheConfig {
    
    @Bean
    public CacheManager cacheManager(RedisConnectionFactory connectionFactory) {
        RedisCacheConfiguration config = RedisCacheConfiguration.defaultCacheConfig()
            .entryTtl(Duration.ofMinutes(30))  // 默认过期时间
            .serializeKeysWith(RedisSerializationContext.SerializationPair
                .fromSerializer(new StringRedisSerializer()))
            .serializeValuesWith(RedisSerializationContext.SerializationPair
                .fromSerializer(new GenericJackson2JsonRedisSerializer()));
        
        return RedisCacheManager.builder(connectionFactory)
            .cacheDefaults(config)
            .withCacheConfiguration("users", config.entryTtl(Duration.ofHours(1)))
            .withCacheConfiguration("products", config.entryTtl(Duration.ofMinutes(10)))
            .build();
    }
}

// 3. 异步配置优化
@Configuration
@EnableAsync
public class AsyncConfig {
    
    @Bean("taskExecutor")
    public ThreadPoolTaskExecutor taskExecutor() {
        ThreadPoolTaskExecutor executor = new ThreadPoolTaskExecutor();
        executor.setCorePoolSize(10);
        executor.setMaxPoolSize(20);
        executor.setQueueCapacity(200);
        executor.setKeepAliveSeconds(60);
        executor.setThreadNamePrefix("async-");
        executor.setRejectedExecutionHandler(new ThreadPoolExecutor.CallerRunsPolicy());
        executor.initialize();
        return executor;
    }
}

2. 业务层优化

java 复制代码
// 1. 批量操作优化
@Service
public class UserService {
    
    @Autowired
    private UserMapper userMapper;
    
    // ❌ 低效:逐个插入
    public void inefficientBatchInsert(List<User> users) {
        for (User user : users) {
            userMapper.insert(user);
        }
    }
    
    // ✅ 高效:批量插入
    public void efficientBatchInsert(List<User> users) {
        userMapper.batchInsert(users);
    }
    
    // 2. 分页查询优化
    public PageResult<User> getUsersWithPagination(int page, int size) {
        // 使用MyBatis Plus分页插件
        Page<User> pageInfo = new Page<>(page, size);
        IPage<User> result = userMapper.selectPage(pageInfo, null);
        
        return PageResult.<User>builder()
            .records(result.getRecords())
            .total(result.getTotal())
            .current(result.getCurrent())
            .size(result.getSize())
            .pages(result.getPages())
            .build();
    }
}

// 2. 缓存策略优化
@Service
public class ProductService {
    
    @Autowired
    private ProductMapper productMapper;
    
    @Cacheable(value = "products", key = "#id", unless = "#result == null")
    public Product getProductById(Long id) {
        return productMapper.selectById(id);
    }
    
    @CacheEvict(value = "products", key = "#product.id")
    public void updateProduct(Product product) {
        productMapper.updateById(product);
    }
    
    @CacheEvict(value = "products", allEntries = true)
    public void clearAllCache() {
        // 清空所有产品缓存
    }
}

// 3. 数据库查询优化
@Repository
public class OrderMapper extends BaseMapper<Order> {
    
    // 使用索引优化查询
    @Select("SELECT * FROM orders WHERE user_id = #{userId} AND status = #{status} " +
            "ORDER BY create_time DESC LIMIT #{offset}, #{limit}")
    List<Order> findOrdersByUserAndStatus(@Param("userId") Long userId, 
                                         @Param("status") String status,
                                         @Param("offset") int offset, 
                                         @Param("limit") int limit);
    
    // 避免N+1查询问题
    @Select("SELECT o.*, u.username, u.email FROM orders o " +
            "LEFT JOIN users u ON o.user_id = u.id " +
            "WHERE o.id IN " +
            "<foreach collection='orderIds' item='id' open='(' separator=',' close=')'>" +
            "#{id}" +
            "</foreach>")
    List<OrderWithUser> findOrdersWithUsers(@Param("orderIds") List<Long> orderIds);
}

四、性能监控工具

1. 应用性能监控

java 复制代码
// 1. 自定义性能监控
@Component
public class PerformanceMonitor {
    
    private final MeterRegistry meterRegistry;
    private final Timer.Sample sample;
    
    public PerformanceMonitor(MeterRegistry meterRegistry) {
        this.meterRegistry = meterRegistry;
        this.sample = Timer.start(meterRegistry);
    }
    
    @EventListener
    public void handleRequest(RequestEvent event) {
        Timer.Sample requestSample = Timer.start(meterRegistry);
        try {
            // 处理请求
            processRequest(event);
        } finally {
            requestSample.stop(Timer.builder("http.request.duration")
                .tag("method", event.getMethod())
                .tag("uri", event.getUri())
                .register(meterRegistry));
        }
    }
    
    private void processRequest(RequestEvent event) {
        // 业务逻辑
    }
}

// 2. 业务指标监控
@Service
public class BusinessMetricsService {
    
    private final Counter orderCounter;
    private final Timer orderProcessingTimer;
    private final Gauge activeUsersGauge;
    
    public BusinessMetricsService(MeterRegistry meterRegistry) {
        this.orderCounter = Counter.builder("orders.created")
            .description("Number of orders created")
            .register(meterRegistry);
            
        this.orderProcessingTimer = Timer.builder("orders.processing.time")
            .description("Order processing time")
            .register(meterRegistry);
            
        this.activeUsersGauge = Gauge.builder("users.active")
            .description("Number of active users")
            .register(meterRegistry, this, BusinessMetricsService::getActiveUserCount);
    }
    
    public void recordOrderCreated() {
        orderCounter.increment();
    }
    
    public void recordOrderProcessingTime(Duration duration) {
        orderProcessingTimer.record(duration);
    }
    
    private double getActiveUserCount() {
        // 返回当前活跃用户数
        return 100.0; // 示例值
    }
}

// 3. 健康检查增强
@Component
public class CustomHealthIndicator implements HealthIndicator {
    
    @Autowired
    private DataSource dataSource;
    
    @Override
    public Health health() {
        try {
            // 检查数据库连接
            try (Connection connection = dataSource.getConnection()) {
                if (connection.isValid(5)) {
                    return Health.up()
                        .withDetail("database", "Available")
                        .withDetail("responseTime", "5ms")
                        .build();
                }
            }
        } catch (Exception e) {
            return Health.down()
                .withDetail("database", "Unavailable")
                .withDetail("error", e.getMessage())
                .build();
        }
        
        return Health.down()
            .withDetail("database", "Unknown status")
            .build();
    }
}

2. 日志监控

java 复制代码
// 1. 结构化日志
@Slf4j
@Service
public class OrderService {
    
    public Order createOrder(OrderRequest request) {
        MDC.put("userId", String.valueOf(request.getUserId()));
        MDC.put("orderId", UUID.randomUUID().toString());
        
        try {
            log.info("Creating order for user: {}", request.getUserId());
            
            Order order = new Order();
            order.setUserId(request.getUserId());
            order.setAmount(request.getAmount());
            order.setStatus("PENDING");
            
            // 业务逻辑
            processOrder(order);
            
            log.info("Order created successfully: {}", order.getId());
            return order;
            
        } catch (Exception e) {
            log.error("Failed to create order for user: {}", request.getUserId(), e);
            throw e;
        } finally {
            MDC.clear();
        }
    }
    
    private void processOrder(Order order) {
        // 订单处理逻辑
    }
}

// 2. 性能日志
@Aspect
@Component
public class PerformanceLoggingAspect {
    
    private static final Logger logger = LoggerFactory.getLogger(PerformanceLoggingAspect.class);
    
    @Around("@annotation(PerformanceLog)")
    public Object logPerformance(ProceedingJoinPoint joinPoint) throws Throwable {
        long startTime = System.currentTimeMillis();
        String methodName = joinPoint.getSignature().getName();
        
        try {
            Object result = joinPoint.proceed();
            long executionTime = System.currentTimeMillis() - startTime;
            
            logger.info("Method {} executed in {} ms", methodName, executionTime);
            return result;
            
        } catch (Exception e) {
            long executionTime = System.currentTimeMillis() - startTime;
            logger.error("Method {} failed after {} ms", methodName, executionTime, e);
            throw e;
        }
    }
}

// 使用注解
@PerformanceLog
@Service
public class UserService {
    
    public User getUserById(Long id) {
        // 业务逻辑
        return new User();
    }
}

五、数据库性能优化

1. 查询优化

java 复制代码
// 1. 索引优化
@Repository
public class OptimizedUserRepository {
    
    // 使用复合索引优化查询
    @Select("SELECT * FROM users WHERE status = #{status} AND created_at >= #{startDate} " +
            "ORDER BY created_at DESC LIMIT #{limit}")
    List<User> findActiveUsersAfterDate(@Param("status") String status,
                                       @Param("startDate") LocalDateTime startDate,
                                       @Param("limit") int limit);
    
    // 避免SELECT *,只查询需要的字段
    @Select("SELECT id, username, email, created_at FROM users WHERE id = #{id}")
    User findUserBasicInfo(@Param("id") Long id);
    
    // 使用EXISTS替代IN
    @Select("SELECT u.* FROM users u WHERE EXISTS " +
            "(SELECT 1 FROM orders o WHERE o.user_id = u.id AND o.status = #{status})")
    List<User> findUsersWithOrders(@Param("status") String status);
}

// 2. 分页优化
@Service
public class PaginationService {
    
    @Autowired
    private UserMapper userMapper;
    
    // 使用游标分页替代OFFSET分页
    public PageResult<User> getUsersWithCursor(Long lastId, int limit) {
        List<User> users = userMapper.findUsersAfterId(lastId, limit);
        
        Long nextCursor = users.isEmpty() ? null : users.get(users.size() - 1).getId();
        boolean hasNext = users.size() == limit;
        
        return PageResult.<User>builder()
            .records(users)
            .nextCursor(nextCursor)
            .hasNext(hasNext)
            .build();
    }
}

// 3. 批量操作优化
@Repository
public class BatchOperationRepository {
    
    @Autowired
    private JdbcTemplate jdbcTemplate;
    
    // 批量插入
    public void batchInsert(List<User> users) {
        String sql = "INSERT INTO users (username, email, created_at) VALUES (?, ?, ?)";
        
        List<Object[]> batchArgs = users.stream()
            .map(user -> new Object[]{user.getUsername(), user.getEmail(), user.getCreatedAt()})
            .collect(Collectors.toList());
        
        jdbcTemplate.batchUpdate(sql, batchArgs);
    }
    
    // 批量更新
    public void batchUpdate(List<User> users) {
        String sql = "UPDATE users SET username = ?, email = ? WHERE id = ?";
        
        List<Object[]> batchArgs = users.stream()
            .map(user -> new Object[]{user.getUsername(), user.getEmail(), user.getId()})
            .collect(Collectors.toList());
        
        jdbcTemplate.batchUpdate(sql, batchArgs);
    }
}

2. 连接池优化

java 复制代码
// 1. HikariCP配置
@Configuration
public class HikariCPConfig {
    
    @Bean
    @ConfigurationProperties("spring.datasource.hikari")
    public HikariConfig hikariConfig() {
        HikariConfig config = new HikariConfig();
        
        // 连接池大小
        config.setMaximumPoolSize(20);
        config.setMinimumIdle(5);
        
        // 连接超时
        config.setConnectionTimeout(30000);
        config.setIdleTimeout(600000);
        config.setMaxLifetime(1800000);
        
        // 连接测试
        config.setConnectionTestQuery("SELECT 1");
        config.setValidationTimeout(5000);
        
        // 性能优化
        config.setLeakDetectionThreshold(60000);
        config.setPoolName("HikariCP");
        
        return config;
    }
}

// 2. 连接池监控
@Component
public class ConnectionPoolMonitor {
    
    @Autowired
    private DataSource dataSource;
    
    @Scheduled(fixedRate = 30000) // 每30秒监控一次
    public void monitorConnectionPool() {
        if (dataSource instanceof HikariDataSource) {
            HikariDataSource hikariDataSource = (HikariDataSource) dataSource;
            HikariPoolMXBean poolBean = hikariDataSource.getHikariPoolMXBean();
            
            log.info("=== 连接池状态 ===");
            log.info("活跃连接数: {}", poolBean.getActiveConnections());
            log.info("空闲连接数: {}", poolBean.getIdleConnections());
            log.info("总连接数: {}", poolBean.getTotalConnections());
            log.info("等待连接的线程数: {}", poolBean.getThreadsAwaitingConnection());
        }
    }
}

六、综合实战练习

1. 性能测试工具

java 复制代码
// 1. 简单的性能测试框架
public class PerformanceTestFramework {
    
    public static void runPerformanceTest(String testName, Runnable test, int iterations) {
        System.out.println("=== 性能测试: " + testName + " ===");
        
        // 预热
        for (int i = 0; i < 10; i++) {
            test.run();
        }
        
        // 正式测试
        long startTime = System.nanoTime();
        for (int i = 0; i < iterations; i++) {
            test.run();
        }
        long endTime = System.nanoTime();
        
        double avgTime = (endTime - startTime) / (double) iterations / 1_000_000; // 转换为毫秒
        System.out.println("平均执行时间: " + String.format("%.2f", avgTime) + " ms");
        System.out.println("总执行时间: " + (endTime - startTime) / 1_000_000 + " ms");
    }
}

// 2. 字符串拼接性能测试
public class StringPerformanceTest {
    
    public static void main(String[] args) {
        String[] words = {"Hello", "World", "Java", "Performance", "Test"};
        int iterations = 100000;
        
        // 测试String拼接
        PerformanceTestFramework.runPerformanceTest(
            "String拼接",
            () -> {
                String result = "";
                for (String word : words) {
                    result += word + " ";
                }
            },
            iterations
        );
        
        // 测试StringBuilder
        PerformanceTestFramework.runPerformanceTest(
            "StringBuilder拼接",
            () -> {
                StringBuilder sb = new StringBuilder();
                for (String word : words) {
                    sb.append(word).append(" ");
                }
                String result = sb.toString();
            },
            iterations
        );
        
        // 测试StringBuffer
        PerformanceTestFramework.runPerformanceTest(
            "StringBuffer拼接",
            () -> {
                StringBuffer sb = new StringBuffer();
                for (String word : words) {
                    sb.append(word).append(" ");
                }
                String result = sb.toString();
            },
            iterations
        );
    }
}

2. 内存泄漏检测

java 复制代码
// 1. 内存泄漏检测工具
public class MemoryLeakDetector {
    
    private static final List<Object> memoryLeak = new ArrayList<>();
    
    public static void simulateMemoryLeak() {
        // 模拟内存泄漏:不断添加对象但不清理
        for (int i = 0; i < 1000; i++) {
            memoryLeak.add(new byte[1024 * 1024]); // 每次添加1MB
        }
    }
    
    public static void clearMemoryLeak() {
        memoryLeak.clear();
        System.gc(); // 建议垃圾回收
    }
    
    public static void printMemoryUsage() {
        MemoryMXBean memoryBean = ManagementFactory.getMemoryMXBean();
        MemoryUsage heapUsage = memoryBean.getHeapMemoryUsage();
        
        System.out.println("堆内存使用: " + formatBytes(heapUsage.getUsed()));
        System.out.println("堆内存最大: " + formatBytes(heapUsage.getMax()));
        System.out.println("使用率: " + 
            String.format("%.2f", (double) heapUsage.getUsed() / heapUsage.getMax() * 100) + "%");
    }
    
    private static String formatBytes(long bytes) {
        return String.format("%.2f MB", bytes / (1024.0 * 1024));
    }
}

// 2. 弱引用防止内存泄漏
public class WeakReferenceExample {
    
    private final Map<String, WeakReference<LargeObject>> cache = new HashMap<>();
    
    public LargeObject getLargeObject(String key) {
        WeakReference<LargeObject> ref = cache.get(key);
        LargeObject obj = ref != null ? ref.get() : null;
        
        if (obj == null) {
            obj = new LargeObject(key);
            cache.put(key, new WeakReference<>(obj));
        }
        
        return obj;
    }
    
    public void clearCache() {
        cache.clear();
    }
    
    // 模拟大对象
    static class LargeObject {
        private final String key;
        private final byte[] data;
        
        public LargeObject(String key) {
            this.key = key;
            this.data = new byte[1024 * 1024]; // 1MB
        }
    }
}

七、性能优化最佳实践

1. 代码优化清单

java 复制代码
// 1. 性能优化检查清单
public class PerformanceChecklist {
    
    /*
     * 代码层面优化:
     * ✅ 使用StringBuilder替代String拼接
     * ✅ 预分配集合容量
     * ✅ 选择合适的集合类型
     * ✅ 避免在循环中调用方法
     * ✅ 使用增强for循环
     * ✅ 及时关闭资源
     * ✅ 避免不必要的对象创建
     * ✅ 使用对象池模式
     * 
     * 数据库优化:
     * ✅ 创建合适的索引
     * ✅ 避免SELECT *
     * ✅ 使用批量操作
     * ✅ 优化分页查询
     * ✅ 使用连接池
     * ✅ 避免N+1查询
     * 
     * 缓存优化:
     * ✅ 合理设置缓存过期时间
     * ✅ 使用缓存预热
     * ✅ 避免缓存穿透
     * ✅ 使用缓存更新策略
     * 
     * JVM优化:
     * ✅ 合理设置堆内存大小
     * ✅ 选择合适的垃圾回收器
     * ✅ 监控GC性能
     * ✅ 使用JVM参数调优
     */
}

2. 性能监控配置

yaml 复制代码
# application.yml - 性能监控配置
management:
  endpoints:
    web:
      exposure:
        include: health,info,metrics,prometheus
  endpoint:
    health:
      show-details: always
  metrics:
    export:
      prometheus:
        enabled: true
    distribution:
      percentiles-histogram:
        http.server.requests: true
      percentiles:
        http.server.requests: 0.5, 0.95, 0.99

# 日志配置
logging:
  level:
    com.example: DEBUG
    org.springframework.web: DEBUG
  pattern:
    console: "%d{yyyy-MM-dd HH:mm:ss} [%thread] %-5level [%X{traceId},%X{spanId}] %logger{36} - %msg%n"
    file: "%d{yyyy-MM-dd HH:mm:ss} [%thread] %-5level [%X{traceId},%X{spanId}] %logger{36} - %msg%n"
  file:
    name: logs/application.log
    max-size: 100MB
    max-history: 30

学习总结

今日重点

  1. 代码层面优化:字符串拼接、集合选择、循环优化
  2. JVM调优:内存管理、垃圾回收、参数配置
  3. Spring Boot优化:连接池、缓存、异步处理
  4. 性能监控:指标收集、日志监控、健康检查
  5. 数据库优化:查询优化、索引设计、批量操作

实践建议

  1. 使用性能测试工具验证优化效果
  2. 建立性能监控体系
  3. 定期进行性能评估
  4. 关注JVM和数据库性能指标
  5. 持续优化和调整
相关推荐
小楼v10 分钟前
说说常见的限流算法及如何使用Redisson实现多机限流
java·后端·redisson·限流算法
与遨游于天地22 分钟前
NIO的三个组件解决三个问题
java·后端·nio
czlczl200209251 小时前
Guava Cache 原理与实战
java·后端·spring
yangminlei1 小时前
Spring 事务探秘:核心机制与应用场景解析
java·spring boot
记得开心一点嘛2 小时前
Redis封装类
java·redis
lkbhua莱克瓦242 小时前
进阶-存储过程3-存储函数
java·数据库·sql·mysql·数据库优化·视图
计算机程序设计小李同学2 小时前
基于SSM框架的动画制作及分享网站设计
java·前端·后端·学习·ssm
鱼跃鹰飞2 小时前
JMM 三大特性(原子性 / 可见性 / 有序性)面试精简版
java·jvm·面试
该怎么办呢3 小时前
基于cesium的三维不动产登记系统的设计与实现(毕业设计)
java·毕业设计
J不A秃V头A3 小时前
多任务执行时,共享请求对象被并发修改
java