1. CPU 性能分析基础

1.1 CPU 性能指标概述

CPU 性能分析是应用程序性能优化的核心环节。通过分析 CPU 使用情况,我们可以:

  • 识别性能瓶颈:找出消耗 CPU 最多的方法和代码路径
  • 优化热点代码:针对性地优化高频执行的代码段
  • 分析调用关系:理解方法调用的层次结构和时间分布
  • 检测性能回归:对比不同版本的性能差异

1.1.1 关键性能指标

// CPU 性能指标示例
import java.lang.management.*;
import java.util.concurrent.*;

public class CPUMetricsExample {
    
    private static final ThreadMXBean threadBean = ManagementFactory.getThreadMXBean();
    private static final OperatingSystemMXBean osBean = ManagementFactory.getOperatingSystemMXBean();
    
    public static void main(String[] args) throws InterruptedException {
        System.out.println("=== CPU Metrics Example ===");
        
        // 启用 CPU 时间测量
        if (threadBean.isCurrentThreadCpuTimeSupported()) {
            threadBean.setThreadCpuTimeEnabled(true);
        }
        
        // 创建不同类型的 CPU 负载
        ExecutorService executor = Executors.newFixedThreadPool(4);
        
        // 提交 CPU 密集型任务
        for (int i = 0; i < 4; i++) {
            final int taskId = i;
            executor.submit(() -> {
                performCPUIntensiveTask(taskId);
            });
        }
        
        // 监控 CPU 使用情况
        monitorCPUUsage(10);
        
        executor.shutdown();
        executor.awaitTermination(30, TimeUnit.SECONDS);
    }
    
    private static void performCPUIntensiveTask(int taskId) {
        System.out.printf("Task %d started on thread: %s%n", 
            taskId, Thread.currentThread().getName());
        
        long startTime = System.nanoTime();
        long startCpuTime = threadBean.getCurrentThreadCpuTime();
        
        // 模拟 CPU 密集型计算
        double result = 0;
        for (int i = 0; i < 10_000_000; i++) {
            result += Math.sin(i) * Math.cos(i) * Math.sqrt(i);
        }
        
        long endTime = System.nanoTime();
        long endCpuTime = threadBean.getCurrentThreadCpuTime();
        
        long wallTime = endTime - startTime;
        long cpuTime = endCpuTime - startCpuTime;
        
        double cpuUtilization = (double) cpuTime / wallTime * 100;
        
        System.out.printf("Task %d completed:%n", taskId);
        System.out.printf("  Wall time: %.2f ms%n", wallTime / 1_000_000.0);
        System.out.printf("  CPU time: %.2f ms%n", cpuTime / 1_000_000.0);
        System.out.printf("  CPU utilization: %.1f%%%n", cpuUtilization);
        System.out.printf("  Result: %.6f%n", result);
        System.out.println();
    }
    
    private static void monitorCPUUsage(int seconds) throws InterruptedException {
        System.out.println("=== CPU Usage Monitoring ===");
        
        for (int i = 0; i < seconds; i++) {
            // 系统 CPU 使用率
            double systemCpuLoad = osBean.getSystemCpuLoad() * 100;
            
            // 进程 CPU 使用率
            double processCpuLoad = osBean.getProcessCpuLoad() * 100;
            
            // 活跃线程数
            int activeThreads = threadBean.getThreadCount();
            
            // 守护线程数
            int daemonThreads = threadBean.getDaemonThreadCount();
            
            System.out.printf("[%02d] System CPU: %5.1f%%, Process CPU: %5.1f%%, " +
                "Threads: %d (Daemon: %d)%n", 
                i + 1, systemCpuLoad, processCpuLoad, activeThreads, daemonThreads);
            
            Thread.sleep(1000);
        }
        
        System.out.println();
    }
 }

4.2 过滤器配置

4.2.1 包和类过滤

合理的过滤器配置可以: - 减少噪音数据 - 专注于业务代码 - 提高分析效率 - 降低性能开销

常用过滤策略

// 过滤器配置示例
import java.util.*;
import java.util.concurrent.*;
import java.util.regex.*;

public class ProfilingFilterExample {
    
    // 定义过滤规则
    private static final Set<String> INCLUDE_PACKAGES = Set.of(
        "com.mycompany",
        "org.myproject"
    );
    
    private static final Set<String> EXCLUDE_PACKAGES = Set.of(
        "java.",
        "javax.",
        "sun.",
        "com.sun.",
        "org.springframework.",
        "org.apache."
    );
    
    private static final Pattern EXCLUDE_PATTERN = Pattern.compile(
        ".*(Test|Mock|Proxy|\\$\\$).*"
    );
    
    public static void main(String[] args) throws InterruptedException {
        System.out.println("=== Profiling Filter Example ===");
        System.out.println("PID: " + ProcessHandle.current().pid());
        
        // 演示过滤效果
        demonstrateFiltering();
    }
    
    private static void demonstrateFiltering() throws InterruptedException {
        ExecutorService executor = Executors.newFixedThreadPool(2);
        
        // 业务代码执行
        executor.submit(() -> {
            BusinessLogic business = new BusinessLogic();
            for (int i = 0; i < 100; i++) {
                business.processBusinessData(i);
                try {
                    Thread.sleep(50);
                } catch (InterruptedException e) {
                    Thread.currentThread().interrupt();
                    break;
                }
            }
        });
        
        // 框架代码执行
        executor.submit(() -> {
            FrameworkCode framework = new FrameworkCode();
            for (int i = 0; i < 100; i++) {
                framework.processFrameworkData(i);
                try {
                    Thread.sleep(30);
                } catch (InterruptedException e) {
                    Thread.currentThread().interrupt();
                    break;
                }
            }
        });
        
        // 模拟过滤采样器
        ScheduledExecutorService sampler = Executors.newSingleThreadScheduledExecutor();
        sampler.scheduleAtFixedRate(() -> {
            sampleWithFilter();
        }, 0, 100, TimeUnit.MILLISECONDS);
        
        // 运行 1 分钟
        Thread.sleep(60_000);
        
        executor.shutdownNow();
        sampler.shutdown();
        
        System.out.println("Filtering demonstration completed");
    }
    
    private static void sampleWithFilter() {
        Map<Thread, StackTraceElement[]> stackTraces = Thread.getAllStackTraces();
        
        for (Map.Entry<Thread, StackTraceElement[]> entry : stackTraces.entrySet()) {
            Thread thread = entry.getKey();
            StackTraceElement[] stack = entry.getValue();
            
            if (thread.getName().startsWith("pool-") && stack.length > 0) {
                // 应用过滤器
                List<StackTraceElement> filteredStack = applyFilter(Arrays.asList(stack));
                
                if (!filteredStack.isEmpty()) {
                    StackTraceElement topFrame = filteredStack.get(0);
                    System.out.printf("[FILTERED] Thread: %s, Method: %s.%s%n", 
                        thread.getName(), 
                        topFrame.getClassName(), 
                        topFrame.getMethodName());
                }
            }
        }
    }
    
    private static List<StackTraceElement> applyFilter(List<StackTraceElement> stack) {
        List<StackTraceElement> filtered = new ArrayList<>();
        
        for (StackTraceElement element : stack) {
            String className = element.getClassName();
            
            // 检查包含规则
            boolean shouldInclude = INCLUDE_PACKAGES.stream()
                .anyMatch(className::startsWith);
            
            // 检查排除规则
            boolean shouldExclude = EXCLUDE_PACKAGES.stream()
                .anyMatch(className::startsWith) ||
                EXCLUDE_PATTERN.matcher(className).matches();
            
            if (shouldInclude && !shouldExclude) {
                filtered.add(element);
            }
        }
        
        return filtered;
    }
    
    // 模拟业务代码
    static class BusinessLogic {
        
        public void processBusinessData(int data) {
            // 业务逻辑处理
            calculateBusinessMetrics(data);
            validateBusinessRules(data);
            updateBusinessState(data);
        }
        
        private void calculateBusinessMetrics(int data) {
            // 业务指标计算
            double result = 0;
            for (int i = 0; i < 1000; i++) {
                result += Math.sin(data + i) * Math.cos(data + i);
            }
            
            // 防止编译器优化
            if (result != 0) {
                System.out.print("");
            }
        }
        
        private void validateBusinessRules(int data) {
            // 业务规则验证
            boolean isValid = data > 0 && data < 1000;
            if (!isValid) {
                throw new IllegalArgumentException("Invalid business data");
            }
        }
        
        private void updateBusinessState(int data) {
            // 业务状态更新
            Map<String, Object> state = new HashMap<>();
            state.put("data", data);
            state.put("timestamp", System.currentTimeMillis());
            state.put("processed", true);
            
            // 模拟状态持久化
            try {
                Thread.sleep(5);
            } catch (InterruptedException e) {
                Thread.currentThread().interrupt();
            }
        }
    }
    
    // 模拟框架代码
    static class FrameworkCode {
        
        public void processFrameworkData(int data) {
            // 框架处理逻辑
            initializeFramework();
            processWithFramework(data);
            cleanupFramework();
        }
        
        private void initializeFramework() {
            // 框架初始化
            for (int i = 0; i < 500; i++) {
                Math.sqrt(i);
            }
        }
        
        private void processWithFramework(int data) {
            // 框架处理
            List<String> items = new ArrayList<>();
            for (int i = 0; i < 100; i++) {
                items.add("framework_item_" + (data + i));
            }
            
            // 框架内部处理
            items.sort(String::compareTo);
        }
        
        private void cleanupFramework() {
            // 框架清理
            System.gc(); // 建议垃圾回收
        }
    }
}

4.2.2 方法级过滤

// 方法级过滤示例
import java.lang.reflect.*;
import java.util.*;
import java.util.concurrent.*;

public class MethodLevelFilterExample {
    
    // 方法过滤规则
    private static final Set<String> EXCLUDE_METHODS = Set.of(
        "toString",
        "hashCode",
        "equals",
        "clone",
        "finalize",
        "wait",
        "notify",
        "notifyAll"
    );
    
    private static final Set<String> FOCUS_METHODS = Set.of(
        "process",
        "calculate",
        "analyze",
        "transform",
        "validate"
    );
    
    public static void main(String[] args) throws InterruptedException {
        System.out.println("=== Method Level Filter Example ===");
        System.out.println("PID: " + ProcessHandle.current().pid());
        
        // 演示方法级过滤
        demonstrateMethodFiltering();
    }
    
    private static void demonstrateMethodFiltering() throws InterruptedException {
        ExecutorService executor = Executors.newFixedThreadPool(1);
        
        executor.submit(() -> {
            DataProcessor processor = new DataProcessor();
            
            for (int i = 0; i < 50; i++) {
                processor.processData("data_" + i);
                try {
                    Thread.sleep(100);
                } catch (InterruptedException e) {
                    Thread.currentThread().interrupt();
                    break;
                }
            }
        });
        
        // 方法级采样
        ScheduledExecutorService sampler = Executors.newSingleThreadScheduledExecutor();
        sampler.scheduleAtFixedRate(() -> {
            sampleWithMethodFilter();
        }, 0, 50, TimeUnit.MILLISECONDS);
        
        // 运行 30 秒
        Thread.sleep(30_000);
        
        executor.shutdownNow();
        sampler.shutdown();
        
        System.out.println("Method filtering demonstration completed");
    }
    
    private static void sampleWithMethodFilter() {
        Map<Thread, StackTraceElement[]> stackTraces = Thread.getAllStackTraces();
        
        for (Map.Entry<Thread, StackTraceElement[]> entry : stackTraces.entrySet()) {
            Thread thread = entry.getKey();
            StackTraceElement[] stack = entry.getValue();
            
            if (thread.getName().startsWith("pool-")) {
                for (StackTraceElement element : stack) {
                    String methodName = element.getMethodName();
                    String className = element.getClassName();
                    
                    // 应用方法过滤
                    if (shouldIncludeMethod(methodName, className)) {
                        System.out.printf("[METHOD_FILTER] %s.%s (line %d)%n", 
                            className, methodName, element.getLineNumber());
                        break; // 只显示第一个匹配的方法
                    }
                }
            }
        }
    }
    
    private static boolean shouldIncludeMethod(String methodName, String className) {
        // 排除系统方法
        if (EXCLUDE_METHODS.contains(methodName)) {
            return false;
        }
        
        // 排除系统类
        if (className.startsWith("java.") || className.startsWith("sun.")) {
            return false;
        }
        
        // 重点关注的方法
        if (FOCUS_METHODS.stream().anyMatch(methodName::contains)) {
            return true;
        }
        
        // 包含业务逻辑的方法
        return className.contains("DataProcessor") || 
               className.contains("BusinessLogic") ||
               className.contains("Service");
    }
    
    static class DataProcessor {
        
        private final Random random = new Random();
        
        public void processData(String data) {
            // 数据处理流程
            validateInput(data);
            String transformed = transformData(data);
            AnalysisResult result = analyzeData(transformed);
            saveResult(result);
        }
        
        private void validateInput(String data) {
            // 输入验证
            if (data == null || data.isEmpty()) {
                throw new IllegalArgumentException("Invalid input data");
            }
            
            // 模拟验证计算
            for (int i = 0; i < 100; i++) {
                Math.sqrt(data.hashCode() + i);
            }
        }
        
        private String transformData(String data) {
            // 数据转换
            StringBuilder transformed = new StringBuilder();
            
            for (char c : data.toCharArray()) {
                transformed.append((char) (c + 1));
            }
            
            // 模拟复杂转换
            for (int i = 0; i < 500; i++) {
                transformed.append("_").append(i);
            }
            
            return transformed.toString();
        }
        
        private AnalysisResult analyzeData(String data) {
            // 数据分析
            double score = calculateScore(data);
            String category = categorizeData(data);
            
            return new AnalysisResult(score, category);
        }
        
        private double calculateScore(String data) {
            // 评分计算
            double score = 0;
            
            for (int i = 0; i < 1000; i++) {
                score += Math.sin(data.hashCode() + i) * Math.cos(i);
            }
            
            return score;
        }
        
        private String categorizeData(String data) {
            // 数据分类
            int hash = data.hashCode();
            
            if (hash % 3 == 0) return "Category_A";
            if (hash % 3 == 1) return "Category_B";
            return "Category_C";
        }
        
        private void saveResult(AnalysisResult result) {
            // 结果保存
            try {
                Thread.sleep(10); // 模拟 I/O
            } catch (InterruptedException e) {
                Thread.currentThread().interrupt();
            }
        }
        
        // 这些方法会被过滤掉
        @Override
        public String toString() {
            return "DataProcessor";
        }
        
        @Override
        public int hashCode() {
            return Objects.hash("DataProcessor");
        }
        
        @Override
        public boolean equals(Object obj) {
            return obj instanceof DataProcessor;
        }
    }
    
    static class AnalysisResult {
        private final double score;
        private final String category;
        
        public AnalysisResult(double score, String category) {
            this.score = score;
            this.category = category;
        }
        
        public double getScore() { return score; }
        public String getCategory() { return category; }
    }
}

5. 实践练习

5.1 练习一:CPU 热点识别

目标:使用 VisualVM 识别和分析 CPU 性能热点

步骤

  1. 运行示例程序
// CPU 热点练习程序
import java.util.*;
import java.util.concurrent.*;

public class CPUHotspotExercise {
    
    private static final Random random = new Random();
    private static final List<String> dataList = new ArrayList<>();
    
    public static void main(String[] args) throws InterruptedException {
        System.out.println("=== CPU Hotspot Exercise ===");
        System.out.println("PID: " + ProcessHandle.current().pid());
        System.out.println("Use VisualVM to identify CPU hotspots");
        
        // 初始化数据
        initializeData();
        
        // 创建性能问题
        ExecutorService executor = Executors.newFixedThreadPool(3);
        
        // 热点 1:低效的字符串操作
        executor.submit(() -> {
            while (!Thread.currentThread().isInterrupted()) {
                inefficientStringOperation();
                try {
                    Thread.sleep(10);
                } catch (InterruptedException e) {
                    Thread.currentThread().interrupt();
                    break;
                }
            }
        });
        
        // 热点 2:低效的集合操作
        executor.submit(() -> {
            while (!Thread.currentThread().isInterrupted()) {
                inefficientCollectionOperation();
                try {
                    Thread.sleep(50);
                } catch (InterruptedException e) {
                    Thread.currentThread().interrupt();
                    break;
                }
            }
        });
        
        // 热点 3:低效的算法
        executor.submit(() -> {
            while (!Thread.currentThread().isInterrupted()) {
                inefficientAlgorithm();
                try {
                    Thread.sleep(100);
                } catch (InterruptedException e) {
                    Thread.currentThread().interrupt();
                    break;
                }
            }
        });
        
        // 运行 5 分钟
        Thread.sleep(300_000);
        
        executor.shutdownNow();
        System.out.println("Exercise completed");
    }
    
    private static void initializeData() {
        for (int i = 0; i < 10000; i++) {
            dataList.add("Item_" + i + "_" + random.nextInt(1000));
        }
    }
    
    // 热点 1:低效的字符串操作
    private static void inefficientStringOperation() {
        String result = "";
        
        // 低效:使用 + 操作符拼接字符串
        for (int i = 0; i < 1000; i++) {
            result += "Item_" + i + ";";
        }
        
        // 低效:重复的字符串操作
        String[] parts = result.split(";");
        for (String part : parts) {
            part.toUpperCase().toLowerCase().trim();
        }
    }
    
    // 热点 2:低效的集合操作
    private static void inefficientCollectionOperation() {
        List<String> result = new ArrayList<>();
        
        // 低效:在循环中频繁查找
        for (String item : dataList) {
            if (!result.contains(item)) { // O(n) 查找
                result.add(item);
            }
        }
        
        // 低效:重复排序
        for (int i = 0; i < 10; i++) {
            Collections.sort(result);
        }
    }
    
    // 热点 3:低效的算法
    private static void inefficientAlgorithm() {
        // 低效:嵌套循环
        int count = 0;
        for (int i = 0; i < 1000; i++) {
            for (int j = 0; j < 1000; j++) {
                if (i * j % 7 == 0) {
                    count++;
                }
            }
        }
        
        // 低效:重复计算
        double result = 0;
        for (int i = 0; i < 5000; i++) {
            result += Math.pow(Math.sin(i), 2) + Math.pow(Math.cos(i), 2);
        }
    }
}
  1. 使用 VisualVM 分析

    • 启动 VisualVM
    • 连接到程序进程
    • 使用 Sampler 进行 CPU 采样
    • 分析 Hot Spots 视图
    • 识别最耗时的方法
  2. 分析结果

    • 记录 Self Time 最高的方法
    • 分析调用次数和平均时间
    • 确定优化优先级

5.2 练习二:调用树分析

目标:理解方法调用关系和时间分布

步骤

  1. 运行调用树示例
// 调用树分析练习
import java.util.*;
import java.util.concurrent.*;

public class CallTreeExercise {
    
    public static void main(String[] args) throws InterruptedException {
        System.out.println("=== Call Tree Exercise ===");
        System.out.println("PID: " + ProcessHandle.current().pid());
        
        OrderProcessor processor = new OrderProcessor();
        
        ExecutorService executor = Executors.newFixedThreadPool(2);
        
        // 处理订单
        for (int i = 0; i < 100; i++) {
            final int orderId = i;
            executor.submit(() -> {
                processor.processOrder("ORDER_" + orderId);
            });
        }
        
        // 等待完成
        executor.shutdown();
        executor.awaitTermination(10, TimeUnit.MINUTES);
        
        System.out.println("Call tree exercise completed");
    }
    
    static class OrderProcessor {
        
        public void processOrder(String orderId) {
            // 第一层调用
            validateOrder(orderId);
            calculatePrice(orderId);
            processPayment(orderId);
            updateInventory(orderId);
        }
        
        private void validateOrder(String orderId) {
            // 第二层调用
            validateFormat(orderId);
            validateBusinessRules(orderId);
            checkInventory(orderId);
        }
        
        private void validateFormat(String orderId) {
            // 第三层调用 - 快速方法
            simulateWork(10);
        }
        
        private void validateBusinessRules(String orderId) {
            // 第三层调用 - 中等耗时
            simulateWork(50);
        }
        
        private void checkInventory(String orderId) {
            // 第三层调用 - 较慢方法
            simulateWork(100);
            queryDatabase(orderId);
        }
        
        private void calculatePrice(String orderId) {
            // 第二层调用
            double basePrice = getBasePrice(orderId);
            double discount = calculateDiscount(orderId);
            double tax = calculateTax(basePrice, discount);
        }
        
        private double getBasePrice(String orderId) {
            // 第三层调用
            simulateWork(30);
            return 100.0;
        }
        
        private double calculateDiscount(String orderId) {
            // 第三层调用 - 复杂计算
            simulateComplexCalculation(200);
            return 10.0;
        }
        
        private double calculateTax(double basePrice, double discount) {
            // 第三层调用
            simulateWork(20);
            return (basePrice - discount) * 0.08;
        }
        
        private void processPayment(String orderId) {
            // 第二层调用
            validatePaymentMethod(orderId);
            chargePayment(orderId);
            recordTransaction(orderId);
        }
        
        private void validatePaymentMethod(String orderId) {
            // 第三层调用 - 网络调用
            simulateNetworkCall(80);
        }
        
        private void chargePayment(String orderId) {
            // 第三层调用 - 网络调用
            simulateNetworkCall(150);
        }
        
        private void recordTransaction(String orderId) {
            // 第三层调用 - 数据库操作
            simulateWork(40);
            queryDatabase(orderId);
        }
        
        private void updateInventory(String orderId) {
            // 第二层调用
            simulateWork(60);
            queryDatabase(orderId);
        }
        
        private void queryDatabase(String orderId) {
            // 数据库查询模拟
            simulateWork(100);
        }
        
        private void simulateWork(int milliseconds) {
            try {
                Thread.sleep(milliseconds);
            } catch (InterruptedException e) {
                Thread.currentThread().interrupt();
            }
        }
        
        private void simulateComplexCalculation(int iterations) {
            double result = 0;
            for (int i = 0; i < iterations * 1000; i++) {
                result += Math.sin(i) * Math.cos(i);
            }
            // 防止编译器优化
            if (result != 0) {
                System.out.print("");
            }
        }
        
        private void simulateNetworkCall(int latency) {
            try {
                Thread.sleep(latency);
            } catch (InterruptedException e) {
                Thread.currentThread().interrupt();
            }
        }
    }
}
  1. 使用 Profiler 分析

    • 启动 CPU Profiler
    • 选择 Methods 模式
    • 运行程序并收集数据
    • 查看 Call Tree 视图
    • 分析方法调用层次
  2. 分析要点

    • 识别调用链中的瓶颈
    • 理解时间在调用树中的分布
    • 找出可以优化的调用路径

5.3 练习三:采样配置优化

目标:学习如何配置采样参数以获得最佳分析效果

步骤

  1. 测试不同采样间隔

    • 使用 10ms 间隔采样
    • 使用 50ms 间隔采样
    • 使用 200ms 间隔采样
    • 比较结果差异
  2. 配置过滤器

    • 设置包过滤器,只分析业务代码
    • 排除框架和系统代码
    • 观察过滤效果
  3. 性能影响测试

    • 测量无分析时的程序性能
    • 测量不同采样配置下的性能影响
    • 找到最佳平衡点

6. 本章总结

6.1 关键要点

  1. CPU 性能分析基础

    • 理解采样和插桩的区别
    • 掌握关键性能指标的含义
    • 学会识别不同类型的性能问题
  2. VisualVM CPU 分析功能

    • Sampler:低开销的性能采样
    • Profiler:详细的性能分析
    • 热点识别和调用树分析
  3. 性能热点识别

    • Self Time vs Total Time
    • 调用次数和平均时间
    • 热点方法的优化策略
  4. 采样配置优化

    • 采样间隔的选择
    • 过滤器的配置
    • 性能开销的平衡

6.2 最佳实践

  1. 分析策略

    • 先用 Sampler 快速定位问题
    • 再用 Profiler 详细分析
    • 关注 Self Time 高的方法
    • 分析调用关系和时间分布
  2. 配置建议

    • 开发环境:使用较高采样频率
    • 生产环境:使用较低采样频率
    • 合理配置过滤器减少噪音
    • 定期清理分析数据
  3. 优化指导

    • 优先优化 Self Time 高的方法
    • 关注频繁调用的方法
    • 分析算法复杂度
    • 考虑缓存和预计算
  4. 注意事项

    • 分析工具本身有性能开销
    • 采样结果具有统计性质
    • 需要足够的采样时间
    • 结合业务场景分析结果

6.3 下一步学习

在下一章中,我们将学习: - 垃圾回收分析与调优 - GC 日志分析 - 内存泄漏检测 - GC 参数优化

通过本章的学习,你应该能够熟练使用 VisualVM 进行 CPU 性能分析,识别性能瓶颈,并制定相应的优化策略。

1.2 性能分析方法论

1.2.1 采样 vs 插桩

采样(Sampling): - 定期中断程序执行,记录当前调用栈 - 低开销,适合生产环境 - 统计性结果,可能遗漏短时间执行的方法

插桩(Instrumentation): - 在方法入口和出口插入监控代码 - 精确测量,记录所有方法调用 - 较高开销,可能影响程序性能

// 性能分析方法对比示例
import java.util.*;
import java.util.concurrent.*;

public class ProfilingMethodsComparison {
    
    private static final Random random = new Random();
    private static final Map<String, Long> methodTimes = new ConcurrentHashMap<>();
    
    public static void main(String[] args) throws InterruptedException {
        System.out.println("=== Profiling Methods Comparison ===");
        
        // 演示不同的性能分析方法
        demonstrateSampling();
        System.out.println();
        demonstrateInstrumentation();
    }
    
    // 模拟采样分析
    private static void demonstrateSampling() {
        System.out.println("=== Sampling Profiling Demo ===");
        
        // 启动工作线程
        ExecutorService executor = Executors.newFixedThreadPool(2);
        
        executor.submit(() -> {
            for (int i = 0; i < 1000; i++) {
                fastMethod();
                if (i % 100 == 0) {
                    slowMethod();
                }
            }
        });
        
        executor.submit(() -> {
            for (int i = 0; i < 500; i++) {
                mediumMethod();
            }
        });
        
        // 模拟采样器
        ScheduledExecutorService sampler = Executors.newSingleThreadScheduledExecutor();
        sampler.scheduleAtFixedRate(() -> {
            // 获取所有线程的栈跟踪
            Map<Thread, StackTraceElement[]> stackTraces = Thread.getAllStackTraces();
            
            for (Map.Entry<Thread, StackTraceElement[]> entry : stackTraces.entrySet()) {
                Thread thread = entry.getKey();
                StackTraceElement[] stack = entry.getValue();
                
                if (thread.getName().startsWith("pool-") && stack.length > 0) {
                    StackTraceElement topFrame = stack[0];
                    String methodName = topFrame.getMethodName();
                    
                    if (methodName.endsWith("Method")) {
                        methodTimes.merge(methodName, 1L, Long::sum);
                    }
                }
            }
        }, 0, 10, TimeUnit.MILLISECONDS);
        
        try {
            Thread.sleep(5000); // 运行 5 秒
        } catch (InterruptedException e) {
            Thread.currentThread().interrupt();
        }
        
        executor.shutdown();
        sampler.shutdown();
        
        // 输出采样结果
        System.out.println("Sampling results (sample count):");
        methodTimes.entrySet().stream()
            .sorted(Map.Entry.<String, Long>comparingByValue().reversed())
            .forEach(entry -> 
                System.out.printf("  %s: %d samples%n", entry.getKey(), entry.getValue()));
    }
    
    // 模拟插桩分析
    private static void demonstrateInstrumentation() {
        System.out.println("=== Instrumentation Profiling Demo ===");
        
        Map<String, Long> exactTimes = new HashMap<>();
        Map<String, Integer> callCounts = new HashMap<>();
        
        // 执行被插桩的方法
        for (int i = 0; i < 1000; i++) {
            measureMethod("fastMethod", () -> fastMethod(), exactTimes, callCounts);
            
            if (i % 100 == 0) {
                measureMethod("slowMethod", () -> slowMethod(), exactTimes, callCounts);
            }
            
            if (i % 2 == 0) {
                measureMethod("mediumMethod", () -> mediumMethod(), exactTimes, callCounts);
            }
        }
        
        // 输出插桩结果
        System.out.println("Instrumentation results:");
        exactTimes.entrySet().stream()
            .sorted(Map.Entry.<String, Long>comparingByValue().reversed())
            .forEach(entry -> {
                String method = entry.getKey();
                long totalTime = entry.getValue();
                int calls = callCounts.get(method);
                double avgTime = (double) totalTime / calls / 1_000_000.0;
                
                System.out.printf("  %s: %d calls, %.2f ms total, %.4f ms avg%n", 
                    method, calls, totalTime / 1_000_000.0, avgTime);
            });
    }
    
    private static void measureMethod(String methodName, Runnable method, 
                                    Map<String, Long> times, Map<String, Integer> counts) {
        long start = System.nanoTime();
        method.run();
        long end = System.nanoTime();
        
        times.merge(methodName, end - start, Long::sum);
        counts.merge(methodName, 1, Integer::sum);
    }
    
    private static void fastMethod() {
        // 快速方法:简单计算
        int sum = 0;
        for (int i = 0; i < 100; i++) {
            sum += i;
        }
    }
    
    private static void mediumMethod() {
        // 中等速度方法:字符串操作
        StringBuilder sb = new StringBuilder();
        for (int i = 0; i < 1000; i++) {
            sb.append("item").append(i).append(",");
        }
        sb.toString();
    }
    
    private static void slowMethod() {
        // 慢方法:复杂计算
        double result = 0;
        for (int i = 0; i < 10000; i++) {
            result += Math.sin(i) * Math.cos(i);
        }
        
        // 模拟 I/O 等待
        try {
            Thread.sleep(random.nextInt(10) + 1);
        } catch (InterruptedException e) {
            Thread.currentThread().interrupt();
        }
    }
}

2. VisualVM CPU 分析功能

2.1 Sampler 标签页

2.1.1 CPU 采样配置

VisualVM 的 Sampler 提供了低开销的 CPU 性能分析:

采样设置: - 采样间隔:默认 20ms,可调整为 10ms-1000ms - 采样深度:调用栈的最大深度 - 过滤器:包含/排除特定包或类

采样数据视图: - Hot Spots:按 CPU 时间排序的方法列表 - Call Tree:方法调用树,显示调用关系 - Combined:热点和调用树的组合视图

2.1.2 CPU 采样示例

// CPU 采样分析示例
import java.util.*;
import java.util.concurrent.*;
import java.util.stream.*;

public class CPUSamplingExample {
    
    private static final Random random = new Random();
    private static final List<String> dataList = new ArrayList<>();
    
    public static void main(String[] args) throws InterruptedException {
        System.out.println("=== CPU Sampling Example ===");
        System.out.println("PID: " + ProcessHandle.current().pid());
        System.out.println("Start VisualVM and attach to this process");
        System.out.println("Use Sampler tab to analyze CPU usage");
        
        // 初始化数据
        initializeData();
        
        // 创建不同类型的 CPU 负载
        ExecutorService executor = Executors.newFixedThreadPool(4);
        
        // 任务 1:数据处理
        executor.submit(() -> {
            while (!Thread.currentThread().isInterrupted()) {
                processData();
                try {
                    Thread.sleep(100);
                } catch (InterruptedException e) {
                    Thread.currentThread().interrupt();
                    break;
                }
            }
        });
        
        // 任务 2:数学计算
        executor.submit(() -> {
            while (!Thread.currentThread().isInterrupted()) {
                performMathCalculations();
                try {
                    Thread.sleep(200);
                } catch (InterruptedException e) {
                    Thread.currentThread().interrupt();
                    break;
                }
            }
        });
        
        // 任务 3:字符串操作
        executor.submit(() -> {
            while (!Thread.currentThread().isInterrupted()) {
                performStringOperations();
                try {
                    Thread.sleep(150);
                } catch (InterruptedException e) {
                    Thread.currentThread().interrupt();
                    break;
                }
            }
        });
        
        // 任务 4:集合操作
        executor.submit(() -> {
            while (!Thread.currentThread().isInterrupted()) {
                performCollectionOperations();
                try {
                    Thread.sleep(300);
                } catch (InterruptedException e) {
                    Thread.currentThread().interrupt();
                    break;
                }
            }
        });
        
        // 运行 5 分钟
        System.out.println("Running for 5 minutes. Use VisualVM to analyze...");
        Thread.sleep(300_000);
        
        executor.shutdownNow();
        System.out.println("Example completed.");
    }
    
    private static void initializeData() {
        System.out.println("Initializing data...");
        for (int i = 0; i < 10000; i++) {
            dataList.add("Item_" + i + "_" + random.nextInt(1000));
        }
        System.out.println("Data initialized: " + dataList.size() + " items");
    }
    
    // CPU 密集型:数据处理
    private static void processData() {
        List<String> filtered = dataList.stream()
            .filter(s -> s.contains("5"))
            .map(String::toUpperCase)
            .sorted()
            .collect(Collectors.toList());
        
        // 进一步处理
        Map<Character, Long> charCount = filtered.stream()
            .flatMapToInt(String::chars)
            .mapToObj(c -> (char) c)
            .collect(Collectors.groupingBy(
                c -> c, 
                Collectors.counting()
            ));
        
        // 模拟结果使用
        if (charCount.size() > 0) {
            // 防止编译器优化
            System.out.print("");
        }
    }
    
    // CPU 密集型:数学计算
    private static void performMathCalculations() {
        double result = 0;
        
        // 复杂数学运算
        for (int i = 0; i < 50000; i++) {
            double x = random.nextDouble() * 100;
            result += Math.sin(x) * Math.cos(x) + Math.sqrt(x) + Math.log(x + 1);
        }
        
        // 矩阵运算
        double[][] matrix = new double[100][100];
        for (int i = 0; i < 100; i++) {
            for (int j = 0; j < 100; j++) {
                matrix[i][j] = Math.random();
            }
        }
        
        // 矩阵乘法
        double[][] result_matrix = multiplyMatrix(matrix, matrix);
        
        // 防止编译器优化
        if (result > 0 && result_matrix[0][0] != 0) {
            System.out.print("");
        }
    }
    
    private static double[][] multiplyMatrix(double[][] a, double[][] b) {
        int n = a.length;
        double[][] result = new double[n][n];
        
        for (int i = 0; i < n; i++) {
            for (int j = 0; j < n; j++) {
                for (int k = 0; k < n; k++) {
                    result[i][j] += a[i][k] * b[k][j];
                }
            }
        }
        
        return result;
    }
    
    // CPU 密集型:字符串操作
    private static void performStringOperations() {
        StringBuilder sb = new StringBuilder();
        
        // 字符串拼接
        for (int i = 0; i < 1000; i++) {
            sb.append("String_").append(i).append("_").append(random.nextInt());
            if (i % 100 == 0) {
                sb.append("\n");
            }
        }
        
        String text = sb.toString();
        
        // 字符串处理
        String[] lines = text.split("\n");
        List<String> processed = Arrays.stream(lines)
            .map(line -> line.replaceAll("\d+", "X"))
            .map(String::toLowerCase)
            .filter(line -> line.length() > 50)
            .collect(Collectors.toList());
        
        // 正则表达式处理
        String pattern = "string_\\d+_x";
        long matches = processed.stream()
            .mapToLong(line -> line.split(pattern).length - 1)
            .sum();
        
        // 防止编译器优化
        if (matches > 0) {
            System.out.print("");
        }
    }
    
    // CPU 密集型:集合操作
    private static void performCollectionOperations() {
        // 创建大型集合
        Set<Integer> set1 = new HashSet<>();
        Set<Integer> set2 = new TreeSet<>();
        List<Integer> list = new ArrayList<>();
        
        // 填充数据
        for (int i = 0; i < 10000; i++) {
            int value = random.nextInt(5000);
            set1.add(value);
            set2.add(value + 1000);
            list.add(value);
        }
        
        // 集合运算
        Set<Integer> intersection = new HashSet<>(set1);
        intersection.retainAll(set2);
        
        Set<Integer> union = new HashSet<>(set1);
        union.addAll(set2);
        
        // 排序和搜索
        Collections.sort(list);
        
        int searchCount = 0;
        for (int i = 0; i < 1000; i++) {
            int target = random.nextInt(5000);
            if (Collections.binarySearch(list, target) >= 0) {
                searchCount++;
            }
        }
        
        // 统计操作
        Map<Integer, Integer> frequency = new HashMap<>();
        for (Integer value : list) {
            frequency.merge(value, 1, Integer::sum);
        }
        
        // 防止编译器优化
        if (searchCount > 0 && frequency.size() > 0) {
            System.out.print("");
        }
    }
}

2.2 Profiler 标签页

2.2.1 CPU 性能分析器

Profiler 提供了更详细的 CPU 分析功能:

分析模式: - Methods:分析所有方法调用 - Classes:按类聚合分析结果 - Packages:按包聚合分析结果

过滤选项: - Root Methods:指定分析的入口方法 - Instrumentation Filter:设置插桩范围 - Exclude Time:排除等待时间

2.2.2 性能分析器示例

// CPU Profiler 分析示例
import java.util.*;
import java.util.concurrent.*;

public class CPUProfilerExample {
    
    private static final Random random = new Random();
    
    public static void main(String[] args) throws InterruptedException {
        System.out.println("=== CPU Profiler Example ===");
        System.out.println("PID: " + ProcessHandle.current().pid());
        System.out.println("Use VisualVM Profiler tab for detailed analysis");
        
        // 模拟复杂的业务逻辑
        BusinessLogicSimulator simulator = new BusinessLogicSimulator();
        
        // 运行不同的业务场景
        ExecutorService executor = Executors.newFixedThreadPool(3);
        
        // 场景 1:用户注册流程
        executor.submit(() -> {
            for (int i = 0; i < 100; i++) {
                simulator.userRegistrationFlow("user" + i);
                try {
                    Thread.sleep(50);
                } catch (InterruptedException e) {
                    Thread.currentThread().interrupt();
                    break;
                }
            }
        });
        
        // 场景 2:数据处理流程
        executor.submit(() -> {
            for (int i = 0; i < 50; i++) {
                simulator.dataProcessingFlow(1000);
                try {
                    Thread.sleep(100);
                } catch (InterruptedException e) {
                    Thread.currentThread().interrupt();
                    break;
                }
            }
        });
        
        // 场景 3:报表生成流程
        executor.submit(() -> {
            for (int i = 0; i < 20; i++) {
                simulator.reportGenerationFlow();
                try {
                    Thread.sleep(200);
                } catch (InterruptedException e) {
                    Thread.currentThread().interrupt();
                    break;
                }
            }
        });
        
        // 运行 3 分钟
        Thread.sleep(180_000);
        
        executor.shutdownNow();
        System.out.println("Profiler example completed.");
    }
    
    static class BusinessLogicSimulator {
        
        private final Map<String, Object> cache = new ConcurrentHashMap<>();
        private final List<String> database = new ArrayList<>();
        
        // 用户注册流程
        public void userRegistrationFlow(String username) {
            // 1. 验证用户输入
            if (!validateUserInput(username)) {
                return;
            }
            
            // 2. 检查用户是否存在
            if (checkUserExists(username)) {
                return;
            }
            
            // 3. 生成用户数据
            UserData userData = generateUserData(username);
            
            // 4. 保存到数据库
            saveToDatabase(userData);
            
            // 5. 发送欢迎邮件
            sendWelcomeEmail(userData);
            
            // 6. 更新缓存
            updateCache(username, userData);
        }
        
        // 数据处理流程
        public void dataProcessingFlow(int recordCount) {
            // 1. 加载数据
            List<DataRecord> records = loadDataRecords(recordCount);
            
            // 2. 数据清洗
            List<DataRecord> cleanedRecords = cleanData(records);
            
            // 3. 数据转换
            List<ProcessedData> processedData = transformData(cleanedRecords);
            
            // 4. 数据聚合
            Map<String, Double> aggregatedData = aggregateData(processedData);
            
            // 5. 数据验证
            validateProcessedData(aggregatedData);
            
            // 6. 保存结果
            saveProcessedData(aggregatedData);
        }
        
        // 报表生成流程
        public void reportGenerationFlow() {
            // 1. 查询数据
            List<ReportData> reportData = queryReportData();
            
            // 2. 数据分析
            AnalysisResult analysis = analyzeData(reportData);
            
            // 3. 生成图表
            ChartData chartData = generateCharts(analysis);
            
            // 4. 格式化报表
            String report = formatReport(analysis, chartData);
            
            // 5. 导出报表
            exportReport(report);
        }
        
        // 辅助方法实现
        private boolean validateUserInput(String username) {
            // 模拟输入验证
            return username != null && username.length() >= 3 && 
                   username.matches("[a-zA-Z0-9]+");
        }
        
        private boolean checkUserExists(String username) {
            // 模拟数据库查询
            simulateDBQuery(10);
            return database.contains(username);
        }
        
        private UserData generateUserData(String username) {
            // 模拟用户数据生成
            simulateCPUWork(50);
            return new UserData(username, username + "@example.com");
        }
        
        private void saveToDatabase(UserData userData) {
            // 模拟数据库保存
            simulateDBQuery(20);
            database.add(userData.username);
        }
        
        private void sendWelcomeEmail(UserData userData) {
            // 模拟邮件发送
            simulateNetworkCall(30);
        }
        
        private void updateCache(String key, Object value) {
            // 模拟缓存更新
            cache.put(key, value);
        }
        
        private List<DataRecord> loadDataRecords(int count) {
            // 模拟数据加载
            simulateDBQuery(count / 10);
            
            List<DataRecord> records = new ArrayList<>();
            for (int i = 0; i < count; i++) {
                records.add(new DataRecord("record" + i, random.nextDouble() * 100));
            }
            return records;
        }
        
        private List<DataRecord> cleanData(List<DataRecord> records) {
            // 模拟数据清洗
            simulateCPUWork(records.size() / 10);
            
            return records.stream()
                .filter(r -> r.value > 0)
                .filter(r -> r.name != null)
                .collect(Collectors.toList());
        }
        
        private List<ProcessedData> transformData(List<DataRecord> records) {
            // 模拟数据转换
            simulateCPUWork(records.size() / 5);
            
            return records.stream()
                .map(r -> new ProcessedData(r.name.toUpperCase(), r.value * 1.1))
                .collect(Collectors.toList());
        }
        
        private Map<String, Double> aggregateData(List<ProcessedData> data) {
            // 模拟数据聚合
            simulateCPUWork(data.size() / 20);
            
            return data.stream()
                .collect(Collectors.groupingBy(
                    d -> d.category,
                    Collectors.summingDouble(d -> d.value)
                ));
        }
        
        private void validateProcessedData(Map<String, Double> data) {
            // 模拟数据验证
            simulateCPUWork(data.size());
        }
        
        private void saveProcessedData(Map<String, Double> data) {
            // 模拟保存处理结果
            simulateDBQuery(data.size());
        }
        
        private List<ReportData> queryReportData() {
            // 模拟报表数据查询
            simulateDBQuery(100);
            
            List<ReportData> data = new ArrayList<>();
            for (int i = 0; i < 1000; i++) {
                data.add(new ReportData("item" + i, random.nextDouble() * 1000));
            }
            return data;
        }
        
        private AnalysisResult analyzeData(List<ReportData> data) {
            // 模拟数据分析
            simulateCPUWork(data.size() / 10);
            
            double sum = data.stream().mapToDouble(d -> d.value).sum();
            double avg = sum / data.size();
            double max = data.stream().mapToDouble(d -> d.value).max().orElse(0);
            double min = data.stream().mapToDouble(d -> d.value).min().orElse(0);
            
            return new AnalysisResult(sum, avg, max, min);
        }
        
        private ChartData generateCharts(AnalysisResult analysis) {
            // 模拟图表生成
            simulateCPUWork(200);
            return new ChartData("chart_data");
        }
        
        private String formatReport(AnalysisResult analysis, ChartData chartData) {
            // 模拟报表格式化
            simulateCPUWork(100);
            
            StringBuilder report = new StringBuilder();
            report.append("Report Summary:\n");
            report.append("Total: ").append(analysis.sum).append("\n");
            report.append("Average: ").append(analysis.avg).append("\n");
            report.append("Max: ").append(analysis.max).append("\n");
            report.append("Min: ").append(analysis.min).append("\n");
            
            return report.toString();
        }
        
        private void exportReport(String report) {
            // 模拟报表导出
            simulateNetworkCall(50);
        }
        
        // 模拟不同类型的操作
        private void simulateCPUWork(int iterations) {
            double result = 0;
            for (int i = 0; i < iterations * 1000; i++) {
                result += Math.sin(i) * Math.cos(i);
            }
            // 防止编译器优化
            if (result != 0) {
                System.out.print("");
            }
        }
        
        private void simulateDBQuery(int complexity) {
            try {
                Thread.sleep(complexity); // 模拟数据库延迟
            } catch (InterruptedException e) {
                Thread.currentThread().interrupt();
            }
        }
        
        private void simulateNetworkCall(int latency) {
            try {
                Thread.sleep(latency); // 模拟网络延迟
            } catch (InterruptedException e) {
                Thread.currentThread().interrupt();
            }
        }
    }
    
    // 数据类
    static class UserData {
        final String username;
        final String email;
        
        UserData(String username, String email) {
            this.username = username;
            this.email = email;
        }
    }
    
    static class DataRecord {
        final String name;
        final double value;
        
        DataRecord(String name, double value) {
            this.name = name;
            this.value = value;
        }
    }
    
    static class ProcessedData {
        final String category;
        final double value;
        
        ProcessedData(String category, double value) {
            this.category = category;
            this.value = value;
        }
    }
    
    static class ReportData {
        final String name;
        final double value;
        
        ReportData(String name, double value) {
            this.name = name;
            this.value = value;
        }
    }
    
    static class AnalysisResult {
        final double sum;
        final double avg;
        final double max;
        final double min;
        
        AnalysisResult(double sum, double avg, double max, double min) {
            this.sum = sum;
            this.avg = avg;
            this.max = max;
            this.min = min;
        }
    }
    
    static class ChartData {
        final String data;
        
        ChartData(String data) {
            this.data = data;
        }
    }
}

3. 性能热点识别

3.1 热点方法分析

3.1.1 识别性能瓶颈

在 VisualVM 中识别性能热点的关键指标:

  1. Self Time:方法自身执行时间(不包括调用的其他方法)
  2. Total Time:方法总执行时间(包括调用的其他方法)
  3. Invocation Count:方法调用次数
  4. Average Time:平均执行时间
// 性能热点识别示例
import java.util.*;
import java.util.concurrent.*;
import java.util.stream.*;

public class PerformanceHotspotExample {
    
    private static final Random random = new Random();
    private static final List<String> dataCache = new ArrayList<>();
    
    public static void main(String[] args) throws InterruptedException {
        System.out.println("=== Performance Hotspot Example ===");
        System.out.println("PID: " + ProcessHandle.current().pid());
        System.out.println("This example demonstrates various performance hotspots");
        
        // 初始化数据
        initializeData();
        
        // 运行不同的性能场景
        runPerformanceScenarios();
    }
    
    private static void initializeData() {
        System.out.println("Initializing test data...");
        for (int i = 0; i < 100000; i++) {
            dataCache.add(generateRandomString(50));
        }
        System.out.println("Data initialized: " + dataCache.size() + " items");
    }
    
    private static void runPerformanceScenarios() throws InterruptedException {
        ExecutorService executor = Executors.newFixedThreadPool(4);
        
        // 场景 1:频繁调用的小方法(高调用次数热点)
        executor.submit(() -> {
            System.out.println("Starting frequent small method calls...");
            for (int i = 0; i < 1000000; i++) {
                frequentSmallMethod(i);
            }
            System.out.println("Frequent small method calls completed");
        });
        
        // 场景 2:少量调用的慢方法(高自身时间热点)
        executor.submit(() -> {
            System.out.println("Starting slow method calls...");
            for (int i = 0; i < 100; i++) {
                slowExpensiveMethod(i);
            }
            System.out.println("Slow method calls completed");
        });
        
        // 场景 3:递归调用(深调用栈热点)
        executor.submit(() -> {
            System.out.println("Starting recursive calls...");
            for (int i = 0; i < 50; i++) {
                recursiveMethod(20, i);
            }
            System.out.println("Recursive calls completed");
        });
        
        // 场景 4:字符串处理(内存分配热点)
        executor.submit(() -> {
            System.out.println("Starting string processing...");
            for (int i = 0; i < 1000; i++) {
                stringProcessingHotspot(i);
            }
            System.out.println("String processing completed");
        });
        
        // 等待所有任务完成
        executor.shutdown();
        executor.awaitTermination(10, TimeUnit.MINUTES);
        
        System.out.println("All performance scenarios completed");
    }
    
    // 热点类型 1:频繁调用的小方法
    private static int frequentSmallMethod(int input) {
        // 这个方法会被调用很多次,但每次执行时间很短
        return (input * 31 + 17) % 1000;
    }
    
    // 热点类型 2:少量调用的慢方法
    private static double slowExpensiveMethod(int seed) {
        // 这个方法调用次数少,但每次执行时间很长
        double result = 0;
        
        // CPU 密集型计算
        for (int i = 0; i < 1000000; i++) {
            double x = seed + i * 0.001;
            result += Math.sin(x) * Math.cos(x) + Math.sqrt(Math.abs(x)) + Math.log(x + 1);
        }
        
        // 复杂的数据处理
        List<Double> numbers = new ArrayList<>();
        for (int i = 0; i < 10000; i++) {
            numbers.add(result + random.nextDouble());
        }
        
        // 排序和统计
        Collections.sort(numbers);
        double sum = numbers.stream().mapToDouble(Double::doubleValue).sum();
        double avg = sum / numbers.size();
        
        // 模拟 I/O 延迟
        try {
            Thread.sleep(10);
        } catch (InterruptedException e) {
            Thread.currentThread().interrupt();
        }
        
        return avg;
    }
    
    // 热点类型 3:递归调用
    private static long recursiveMethod(int depth, int value) {
        if (depth <= 0) {
            return fibonacciCalculation(value % 30);
        }
        
        // 递归调用会产生深的调用栈
        long result1 = recursiveMethod(depth - 1, value * 2);
        long result2 = recursiveMethod(depth - 1, value * 3);
        
        return result1 + result2 + expensiveCalculation(value);
    }
    
    private static long fibonacciCalculation(int n) {
        if (n <= 1) return n;
        
        long a = 0, b = 1;
        for (int i = 2; i <= n; i++) {
            long temp = a + b;
            a = b;
            b = temp;
        }
        return b;
    }
    
    private static long expensiveCalculation(int input) {
        long result = 0;
        for (int i = 0; i < 1000; i++) {
            result += (long) Math.pow(input + i, 2) % 10000;
        }
        return result;
    }
    
    // 热点类型 4:字符串处理和内存分配
    private static String stringProcessingHotspot(int iteration) {
        // 大量字符串操作会产生内存分配热点
        StringBuilder result = new StringBuilder();
        
        // 字符串拼接
        for (int i = 0; i < 1000; i++) {
            result.append("Iteration_").append(iteration)
                  .append("_Item_").append(i)
                  .append("_Random_").append(random.nextInt(10000))
                  .append(";");
        }
        
        String text = result.toString();
        
        // 字符串分割和处理
        String[] parts = text.split(";");
        List<String> processed = Arrays.stream(parts)
            .filter(s -> s.length() > 20)
            .map(s -> s.toUpperCase())
            .map(s -> s.replace("_", "-"))
            .collect(Collectors.toList());
        
        // 正则表达式处理
        String pattern = "ITERATION-\\d+-ITEM-\\d+";
        long matches = processed.stream()
            .mapToLong(s -> s.split(pattern).length - 1)
            .sum();
        
        // 字符串查找和替换
        String finalResult = processed.stream()
            .collect(Collectors.joining("|"))
            .replace("RANDOM", "PROC")
            .toLowerCase();
        
        // 模拟字符串缓存查找
        String cachedString = findInCache(finalResult.substring(0, Math.min(50, finalResult.length())));
        
        return finalResult + "_" + matches + "_" + (cachedString != null ? "CACHED" : "NEW");
    }
    
    private static String findInCache(String key) {
        // 模拟在大量数据中查找
        for (String cached : dataCache) {
            if (cached.contains(key.substring(0, Math.min(10, key.length())))) {
                return cached;
            }
        }
        return null;
    }
    
    private static String generateRandomString(int length) {
        StringBuilder sb = new StringBuilder(length);
        String chars = "ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz0123456789";
        
        for (int i = 0; i < length; i++) {
            sb.append(chars.charAt(random.nextInt(chars.length())));
        }
        
        return sb.toString();
    }
}

3.2 调用树分析

3.2.1 理解调用关系

调用树分析帮助我们理解: - 方法调用的层次结构 - 时间在调用链中的分布 - 性能瓶颈的根本原因 - 优化的优先级

// 调用树分析示例
import java.util.*;
import java.util.concurrent.*;

public class CallTreeAnalysisExample {
    
    private static final Random random = new Random();
    
    public static void main(String[] args) throws InterruptedException {
        System.out.println("=== Call Tree Analysis Example ===");
        System.out.println("PID: " + ProcessHandle.current().pid());
        System.out.println("Use VisualVM Profiler to analyze call tree");
        
        // 创建复杂的调用链
        BusinessService service = new BusinessService();
        
        ExecutorService executor = Executors.newFixedThreadPool(2);
        
        // 场景 1:订单处理流程
        executor.submit(() -> {
            for (int i = 0; i < 50; i++) {
                service.processOrder("ORDER_" + i);
                try {
                    Thread.sleep(100);
                } catch (InterruptedException e) {
                    Thread.currentThread().interrupt();
                    break;
                }
            }
        });
        
        // 场景 2:用户分析流程
        executor.submit(() -> {
            for (int i = 0; i < 30; i++) {
                service.analyzeUserBehavior("USER_" + i);
                try {
                    Thread.sleep(200);
                } catch (InterruptedException e) {
                    Thread.currentThread().interrupt();
                    break;
                }
            }
        });
        
        // 运行 2 分钟
        Thread.sleep(120_000);
        
        executor.shutdownNow();
        System.out.println("Call tree analysis example completed");
    }
    
    static class BusinessService {
        
        private final DatabaseService dbService = new DatabaseService();
        private final CacheService cacheService = new CacheService();
        private final ValidationService validationService = new ValidationService();
        private final NotificationService notificationService = new NotificationService();
        private final AnalyticsService analyticsService = new AnalyticsService();
        
        // 主业务流程:订单处理
        public void processOrder(String orderId) {
            System.out.println("Processing order: " + orderId);
            
            // 1. 验证订单
            if (!validateOrder(orderId)) {
                return;
            }
            
            // 2. 检查库存
            if (!checkInventory(orderId)) {
                return;
            }
            
            // 3. 计算价格
            double price = calculatePrice(orderId);
            
            // 4. 处理支付
            if (!processPayment(orderId, price)) {
                return;
            }
            
            // 5. 更新库存
            updateInventory(orderId);
            
            // 6. 发送通知
            sendOrderConfirmation(orderId);
            
            // 7. 记录分析数据
            recordOrderAnalytics(orderId, price);
        }
        
        // 主业务流程:用户行为分析
        public void analyzeUserBehavior(String userId) {
            System.out.println("Analyzing user behavior: " + userId);
            
            // 1. 获取用户数据
            UserData userData = getUserData(userId);
            
            // 2. 分析浏览历史
            BrowsingHistory history = analyzeBrowsingHistory(userId);
            
            // 3. 计算用户偏好
            UserPreferences preferences = calculateUserPreferences(userData, history);
            
            // 4. 生成推荐
            List<Recommendation> recommendations = generateRecommendations(preferences);
            
            // 5. 更新用户画像
            updateUserProfile(userId, preferences);
            
            // 6. 发送个性化内容
            sendPersonalizedContent(userId, recommendations);
        }
        
        // 订单验证流程
        private boolean validateOrder(String orderId) {
            // 多层验证调用
            return validationService.validateOrderFormat(orderId) &&
                   validationService.validateOrderData(orderId) &&
                   validationService.validateBusinessRules(orderId);
        }
        
        private boolean checkInventory(String orderId) {
            // 先检查缓存,再查数据库
            String cacheKey = "inventory_" + orderId;
            Integer stock = cacheService.getInteger(cacheKey);
            
            if (stock == null) {
                stock = dbService.queryInventory(orderId);
                cacheService.put(cacheKey, stock);
            }
            
            return stock > 0;
        }
        
        private double calculatePrice(String orderId) {
            // 复杂的价格计算
            double basePrice = dbService.getBasePrice(orderId);
            double discount = calculateDiscount(orderId);
            double tax = calculateTax(basePrice, discount);
            
            return basePrice - discount + tax;
        }
        
        private double calculateDiscount(String orderId) {
            // 多种折扣规则
            double userDiscount = calculateUserDiscount(orderId);
            double seasonalDiscount = calculateSeasonalDiscount();
            double volumeDiscount = calculateVolumeDiscount(orderId);
            
            return Math.max(userDiscount, Math.max(seasonalDiscount, volumeDiscount));
        }
        
        private double calculateUserDiscount(String orderId) {
            String userId = dbService.getUserIdByOrder(orderId);
            UserData userData = dbService.getUserData(userId);
            
            // 基于用户等级的折扣
            return userData.getLevel() * 0.05;
        }
        
        private double calculateSeasonalDiscount() {
            // 模拟季节性折扣计算
            simulateComplexCalculation(100);
            return random.nextDouble() * 0.1;
        }
        
        private double calculateVolumeDiscount(String orderId) {
            int quantity = dbService.getOrderQuantity(orderId);
            
            if (quantity >= 100) return 0.15;
            if (quantity >= 50) return 0.10;
            if (quantity >= 10) return 0.05;
            return 0.0;
        }
        
        private double calculateTax(double basePrice, double discount) {
            double taxableAmount = basePrice - discount;
            return taxableAmount * 0.08; // 8% 税率
        }
        
        private boolean processPayment(String orderId, double amount) {
            // 支付处理流程
            return validatePaymentMethod(orderId) &&
                   chargePayment(orderId, amount) &&
                   recordPaymentTransaction(orderId, amount);
        }
        
        private boolean validatePaymentMethod(String orderId) {
            // 支付方式验证
            simulateNetworkCall(50);
            return true;
        }
        
        private boolean chargePayment(String orderId, double amount) {
            // 实际扣款
            simulateNetworkCall(100);
            return true;
        }
        
        private boolean recordPaymentTransaction(String orderId, double amount) {
            // 记录支付事务
            dbService.insertPaymentRecord(orderId, amount);
            return true;
        }
        
        private void updateInventory(String orderId) {
            int quantity = dbService.getOrderQuantity(orderId);
            dbService.updateInventory(orderId, quantity);
            
            // 清除相关缓存
            cacheService.remove("inventory_" + orderId);
        }
        
        private void sendOrderConfirmation(String orderId) {
            String userId = dbService.getUserIdByOrder(orderId);
            notificationService.sendEmail(userId, "Order Confirmation");
            notificationService.sendSMS(userId, "Order confirmed");
        }
        
        private void recordOrderAnalytics(String orderId, double price) {
            analyticsService.recordOrderEvent(orderId, price);
            analyticsService.updateUserMetrics(dbService.getUserIdByOrder(orderId));
        }
        
        // 用户行为分析相关方法
        private UserData getUserData(String userId) {
            // 先查缓存
            UserData cached = cacheService.getUserData(userId);
            if (cached != null) {
                return cached;
            }
            
            // 查数据库
            UserData userData = dbService.getUserData(userId);
            cacheService.putUserData(userId, userData);
            
            return userData;
        }
        
        private BrowsingHistory analyzeBrowsingHistory(String userId) {
            List<BrowsingEvent> events = dbService.getBrowsingHistory(userId);
            return analyticsService.analyzeBrowsingPattern(events);
        }
        
        private UserPreferences calculateUserPreferences(UserData userData, BrowsingHistory history) {
            // 复杂的偏好计算
            return analyticsService.calculatePreferences(userData, history);
        }
        
        private List<Recommendation> generateRecommendations(UserPreferences preferences) {
            return analyticsService.generateRecommendations(preferences);
        }
        
        private void updateUserProfile(String userId, UserPreferences preferences) {
            dbService.updateUserProfile(userId, preferences);
            cacheService.remove("user_" + userId); // 清除缓存
        }
        
        private void sendPersonalizedContent(String userId, List<Recommendation> recommendations) {
            notificationService.sendPersonalizedEmail(userId, recommendations);
        }
        
        // 辅助方法
        private void simulateComplexCalculation(int iterations) {
            double result = 0;
            for (int i = 0; i < iterations * 1000; i++) {
                result += Math.sin(i) * Math.cos(i);
            }
            // 防止编译器优化
            if (result != 0) {
                System.out.print("");
            }
        }
        
        private void simulateNetworkCall(int latency) {
            try {
                Thread.sleep(latency);
            } catch (InterruptedException e) {
                Thread.currentThread().interrupt();
            }
        }
    }
    
    // 服务类
    static class DatabaseService {
        
        public Integer queryInventory(String orderId) {
            simulateDBQuery(30);
            return random.nextInt(100) + 1;
        }
        
        public double getBasePrice(String orderId) {
            simulateDBQuery(20);
            return random.nextDouble() * 1000 + 100;
        }
        
        public String getUserIdByOrder(String orderId) {
            simulateDBQuery(15);
            return "USER_" + orderId.hashCode();
        }
        
        public UserData getUserData(String userId) {
            simulateDBQuery(40);
            return new UserData(userId, random.nextInt(5) + 1);
        }
        
        public int getOrderQuantity(String orderId) {
            simulateDBQuery(10);
            return random.nextInt(20) + 1;
        }
        
        public void insertPaymentRecord(String orderId, double amount) {
            simulateDBQuery(25);
        }
        
        public void updateInventory(String orderId, int quantity) {
            simulateDBQuery(35);
        }
        
        public List<BrowsingEvent> getBrowsingHistory(String userId) {
            simulateDBQuery(60);
            List<BrowsingEvent> events = new ArrayList<>();
            for (int i = 0; i < 50; i++) {
                events.add(new BrowsingEvent("page_" + i));
            }
            return events;
        }
        
        public void updateUserProfile(String userId, UserPreferences preferences) {
            simulateDBQuery(30);
        }
        
        private void simulateDBQuery(int latency) {
            try {
                Thread.sleep(latency);
            } catch (InterruptedException e) {
                Thread.currentThread().interrupt();
            }
        }
    }
    
    static class CacheService {
        private final Map<String, Object> cache = new ConcurrentHashMap<>();
        
        public Integer getInteger(String key) {
            return (Integer) cache.get(key);
        }
        
        public void put(String key, Object value) {
            cache.put(key, value);
        }
        
        public UserData getUserData(String userId) {
            return (UserData) cache.get("user_" + userId);
        }
        
        public void putUserData(String userId, UserData userData) {
            cache.put("user_" + userId, userData);
        }
        
        public void remove(String key) {
            cache.remove(key);
        }
    }
    
    static class ValidationService {
        
        public boolean validateOrderFormat(String orderId) {
            simulateValidation(10);
            return orderId != null && orderId.startsWith("ORDER_");
        }
        
        public boolean validateOrderData(String orderId) {
            simulateValidation(20);
            return orderId.length() > 6;
        }
        
        public boolean validateBusinessRules(String orderId) {
            simulateValidation(30);
            return true; // 模拟业务规则验证
        }
        
        private void simulateValidation(int complexity) {
            // 模拟验证计算
            for (int i = 0; i < complexity * 100; i++) {
                Math.sqrt(i);
            }
        }
    }
    
    static class NotificationService {
        
        public void sendEmail(String userId, String subject) {
            simulateNetworkCall(80);
        }
        
        public void sendSMS(String userId, String message) {
            simulateNetworkCall(50);
        }
        
        public void sendPersonalizedEmail(String userId, List<Recommendation> recommendations) {
            simulateNetworkCall(120);
        }
        
        private void simulateNetworkCall(int latency) {
            try {
                Thread.sleep(latency);
            } catch (InterruptedException e) {
                Thread.currentThread().interrupt();
            }
        }
    }
    
    static class AnalyticsService {
        
        public void recordOrderEvent(String orderId, double price) {
            simulateAnalytics(40);
        }
        
        public void updateUserMetrics(String userId) {
            simulateAnalytics(30);
        }
        
        public BrowsingHistory analyzeBrowsingPattern(List<BrowsingEvent> events) {
            simulateAnalytics(events.size());
            return new BrowsingHistory(events);
        }
        
        public UserPreferences calculatePreferences(UserData userData, BrowsingHistory history) {
            simulateAnalytics(200);
            return new UserPreferences(userData.getLevel());
        }
        
        public List<Recommendation> generateRecommendations(UserPreferences preferences) {
            simulateAnalytics(150);
            List<Recommendation> recommendations = new ArrayList<>();
            for (int i = 0; i < 10; i++) {
                recommendations.add(new Recommendation("item_" + i));
            }
            return recommendations;
        }
        
        private void simulateAnalytics(int complexity) {
            // 模拟分析计算
            double result = 0;
            for (int i = 0; i < complexity * 100; i++) {
                result += Math.sin(i) * Math.cos(i);
            }
            // 防止编译器优化
            if (result != 0) {
                System.out.print("");
            }
        }
    }
    
    // 数据类
    static class UserData {
        private final String userId;
        private final int level;
        
        public UserData(String userId, int level) {
            this.userId = userId;
            this.level = level;
        }
        
        public String getUserId() { return userId; }
        public int getLevel() { return level; }
    }
    
    static class BrowsingEvent {
        private final String page;
        
        public BrowsingEvent(String page) {
            this.page = page;
        }
        
        public String getPage() { return page; }
    }
    
    static class BrowsingHistory {
        private final List<BrowsingEvent> events;
        
        public BrowsingHistory(List<BrowsingEvent> events) {
            this.events = events;
        }
        
        public List<BrowsingEvent> getEvents() { return events; }
    }
    
    static class UserPreferences {
        private final int level;
        
        public UserPreferences(int level) {
            this.level = level;
        }
        
        public int getLevel() { return level; }
    }
    
    static class Recommendation {
        private final String item;
        
        public Recommendation(String item) {
            this.item = item;
        }
        
        public String getItem() { return item; }
    }
}

4. CPU 采样配置与优化

4.1 采样参数调优

4.1.1 采样间隔设置

采样间隔的选择需要平衡精度和性能开销:

  • 高频采样(10ms)

    • 优点:更精确的性能数据
    • 缺点:较高的性能开销
    • 适用:开发环境,短期性能分析
  • 中频采样(20ms,默认)

    • 优点:平衡精度和开销
    • 缺点:可能遗漏短时间执行的方法
    • 适用:大多数性能分析场景
  • 低频采样(100ms+)

    • 优点:最低性能开销
    • 缺点:精度较低
    • 适用:生产环境长期监控
// 采样配置优化示例
import java.lang.management.*;
import java.util.concurrent.*;

public class SamplingConfigurationExample {
    
    private static final ThreadMXBean threadBean = ManagementFactory.getThreadMXBean();
    
    public static void main(String[] args) throws InterruptedException {
        System.out.println("=== Sampling Configuration Example ===");
        System.out.println("PID: " + ProcessHandle.current().pid());
        
        // 启用线程 CPU 时间测量
        if (threadBean.isCurrentThreadCpuTimeSupported()) {
            threadBean.setThreadCpuTimeEnabled(true);
        }
        
        // 演示不同采样频率的效果
        demonstrateSamplingFrequency();
    }
    
    private static void demonstrateSamplingFrequency() throws InterruptedException {
        System.out.println("\n=== Sampling Frequency Demonstration ===");
        
        ExecutorService executor = Executors.newFixedThreadPool(3);
        
        // 创建不同类型的工作负载
        executor.submit(() -> createShortBurstWorkload());
        executor.submit(() -> createSteadyWorkload());
        executor.submit(() -> createIntermittentWorkload());
        
        // 模拟不同频率的采样器
        ScheduledExecutorService highFreqSampler = Executors.newSingleThreadScheduledExecutor();
        ScheduledExecutorService mediumFreqSampler = Executors.newSingleThreadScheduledExecutor();
        ScheduledExecutorService lowFreqSampler = Executors.newSingleThreadScheduledExecutor();
        
        // 高频采样(10ms)
        highFreqSampler.scheduleAtFixedRate(() -> {
            sampleThreads("HIGH_FREQ");
        }, 0, 10, TimeUnit.MILLISECONDS);
        
        // 中频采样(50ms)
        mediumFreqSampler.scheduleAtFixedRate(() -> {
            sampleThreads("MEDIUM_FREQ");
        }, 0, 50, TimeUnit.MILLISECONDS);
        
        // 低频采样(200ms)
        lowFreqSampler.scheduleAtFixedRate(() -> {
            sampleThreads("LOW_FREQ");
        }, 0, 200, TimeUnit.MILLISECONDS);
        
        // 运行 30 秒
        Thread.sleep(30_000);
        
        // 关闭所有服务
        executor.shutdownNow();
        highFreqSampler.shutdown();
        mediumFreqSampler.shutdown();
        lowFreqSampler.shutdown();
        
        System.out.println("Sampling demonstration completed");
    }
    
    private static void sampleThreads(String samplerType) {
        Map<Thread, StackTraceElement[]> stackTraces = Thread.getAllStackTraces();
        
        for (Map.Entry<Thread, StackTraceElement[]> entry : stackTraces.entrySet()) {
            Thread thread = entry.getKey();
            StackTraceElement[] stack = entry.getValue();
            
            if (thread.getName().startsWith("pool-") && stack.length > 0) {
                StackTraceElement topFrame = stack[0];
                String methodName = topFrame.getMethodName();
                
                // 记录采样数据(实际应用中会存储到数据结构中)
                if (methodName.contains("Workload")) {
                    System.out.printf("[%s] Thread: %s, Method: %s%n", 
                        samplerType, thread.getName(), methodName);
                }
            }
        }
    }
    
    // 短时间突发工作负载
    private static void createShortBurstWorkload() {
        while (!Thread.currentThread().isInterrupted()) {
            try {
                // 短时间高强度计算
                shortBurstCalculation();
                
                // 长时间休眠
                Thread.sleep(1000);
            } catch (InterruptedException e) {
                Thread.currentThread().interrupt();
                break;
            }
        }
    }
    
    private static void shortBurstCalculation() {
        // 5ms 的密集计算
        long endTime = System.currentTimeMillis() + 5;
        double result = 0;
        
        while (System.currentTimeMillis() < endTime) {
            for (int i = 0; i < 1000; i++) {
                result += Math.sin(i) * Math.cos(i);
            }
        }
        
        // 防止编译器优化
        if (result != 0) {
            System.out.print("");
        }
    }
    
    // 稳定工作负载
    private static void createSteadyWorkload() {
        while (!Thread.currentThread().isInterrupted()) {
            try {
                steadyCalculation();
                Thread.sleep(10); // 短暂休息
            } catch (InterruptedException e) {
                Thread.currentThread().interrupt();
                break;
            }
        }
    }
    
    private static void steadyCalculation() {
        // 稳定的计算负载
        double result = 0;
        for (int i = 0; i < 10000; i++) {
            result += Math.sqrt(i);
        }
        
        // 防止编译器优化
        if (result != 0) {
            System.out.print("");
        }
    }
    
    // 间歇性工作负载
    private static void createIntermittentWorkload() {
        while (!Thread.currentThread().isInterrupted()) {
            try {
                // 随机工作时间
                if (Math.random() < 0.3) {
                    intermittentCalculation();
                }
                
                Thread.sleep(50);
            } catch (InterruptedException e) {
                Thread.currentThread().interrupt();
                break;
            }
        }
    }
    
    private static void intermittentCalculation() {
        // 间歇性计算
        double result = 0;
        int iterations = (int) (Math.random() * 50000);
        
        for (int i = 0; i < iterations; i++) {
            result += Math.log(i + 1);
        }
        
        // 防止编译器优化
        if (result != 0) {
            System.out.print("");
        }
    }
}