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. 持续优化和调整
相关推荐
纪莫4 小时前
技术面:Java并发(线程同步、死锁、多线程编排)
java·java面试⑧股
衍余未了4 小时前
k8s 内置的containerd配置阿里云个人镜像地址及认证
java·阿里云·kubernetes
叽哥4 小时前
Kotlin学习第 4 课:Kotlin 函数:从基础定义到高阶应用
android·java·kotlin
渣哥4 小时前
使用 HashMap 提高性能的小技巧
java
kyle~4 小时前
排序---快速排序(Quick Sort)
java·开发语言
小蒜学长4 小时前
旅行社旅游管理系统的设计与实现(代码+数据库+LW)
java·数据库·spring boot·后端·旅游
Kevinyu_4 小时前
RabbitMQ
java·rabbitmq·java-rabbitmq