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 性能热点
步骤:
- 运行示例程序:
// 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);
}
}
}
使用 VisualVM 分析:
- 启动 VisualVM
- 连接到程序进程
- 使用 Sampler 进行 CPU 采样
- 分析 Hot Spots 视图
- 识别最耗时的方法
分析结果:
- 记录 Self Time 最高的方法
- 分析调用次数和平均时间
- 确定优化优先级
5.2 练习二:调用树分析
目标:理解方法调用关系和时间分布
步骤:
- 运行调用树示例:
// 调用树分析练习
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();
}
}
}
}
使用 Profiler 分析:
- 启动 CPU Profiler
- 选择 Methods 模式
- 运行程序并收集数据
- 查看 Call Tree 视图
- 分析方法调用层次
分析要点:
- 识别调用链中的瓶颈
- 理解时间在调用树中的分布
- 找出可以优化的调用路径
5.3 练习三:采样配置优化
目标:学习如何配置采样参数以获得最佳分析效果
步骤:
测试不同采样间隔:
- 使用 10ms 间隔采样
- 使用 50ms 间隔采样
- 使用 200ms 间隔采样
- 比较结果差异
配置过滤器:
- 设置包过滤器,只分析业务代码
- 排除框架和系统代码
- 观察过滤效果
性能影响测试:
- 测量无分析时的程序性能
- 测量不同采样配置下的性能影响
- 找到最佳平衡点
6. 本章总结
6.1 关键要点
CPU 性能分析基础:
- 理解采样和插桩的区别
- 掌握关键性能指标的含义
- 学会识别不同类型的性能问题
VisualVM CPU 分析功能:
- Sampler:低开销的性能采样
- Profiler:详细的性能分析
- 热点识别和调用树分析
性能热点识别:
- Self Time vs Total Time
- 调用次数和平均时间
- 热点方法的优化策略
采样配置优化:
- 采样间隔的选择
- 过滤器的配置
- 性能开销的平衡
6.2 最佳实践
分析策略:
- 先用 Sampler 快速定位问题
- 再用 Profiler 详细分析
- 关注 Self Time 高的方法
- 分析调用关系和时间分布
配置建议:
- 开发环境:使用较高采样频率
- 生产环境:使用较低采样频率
- 合理配置过滤器减少噪音
- 定期清理分析数据
优化指导:
- 优先优化 Self Time 高的方法
- 关注频繁调用的方法
- 分析算法复杂度
- 考虑缓存和预计算
注意事项:
- 分析工具本身有性能开销
- 采样结果具有统计性质
- 需要足够的采样时间
- 结合业务场景分析结果
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 中识别性能热点的关键指标:
- Self Time:方法自身执行时间(不包括调用的其他方法)
- Total Time:方法总执行时间(包括调用的其他方法)
- Invocation Count:方法调用次数
- 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("");
}
}
}