JVM架构:内存模型与GC算法
JVM架构:内存模型与GC算法
JVM内存模型
JVM内存分为堆、栈、方法区、程序计数器等区域,理解内存模型是性能调优的基础。
// JVM内存监控
@Component
public class JVMMemoryMonitor {
private final MemoryMXBean memoryBean;
private final List<GarbageCollectorMXBean> gcBeans;
private final MetricsExporter metrics;
@Scheduled(fixedRate = 5000)
public void monitorMemory() {
// 堆内存
MemoryUsage heapUsage = memoryBean.getHeapMemoryUsage();
metrics.gauge("jvm.heap.used", heapUsage.getUsed());
metrics.gauge("jvm.heap.committed", heapUsage.getCommitted());
metrics.gauge("jvm.heap.max", heapUsage.getMax());
metrics.gauge("jvm.heap.usage",
(double) heapUsage.getUsed() / heapUsage.getMax() * 100);
// 非堆内存
MemoryUsage nonHeapUsage = memoryBean.getNonHeapMemoryUsage();
metrics.gauge("jvm.nonheap.used", nonHeapUsage.getUsed());
metrics.gauge("jvm.nonheap.committed", nonHeapUsage.getCommitted());
// 各内存池
MemoryPoolMXBean[] memoryPools = ManagementFactory.getMemoryPoolMXBeans();
for (MemoryPoolMXBean pool : memoryPools) {
String name = pool.getName().toLowerCase().replace(" ", "_");
MemoryUsage usage = pool.getUsage();
metrics.gauge("jvm.memory_pool." + name + ".used", usage.getUsed());
metrics.gauge("jvm.memory_pool." + name + ".max", usage.getMax());
}
// GC统计
for (GarbageCollectorMXBean gcBean : gcBeans) {
String name = gcBean.getName().toLowerCase().replace(" ", "_");
metrics.counter("jvm.gc." + name + ".count", gcBean.getCollectionCount());
metrics.counter("jvm.gc." + name + ".time", gcBean.getCollectionTime());
}
}
}
// 内存泄漏检测
@Component
public class MemoryLeakDetector {
public void detect() {
// 获取内存池信息
MemoryPoolMXBean[] pools = ManagementFactory.getMemoryPoolMXBeans();
for (MemoryPoolMXBean pool : pools) {
if (pool.isUsageThresholdSupported()) {
MemoryUsage usage = pool.getUsage();
long used = usage.getUsed();
long max = usage.getMax();
// 检查内存使用率
if (max > 0 && (double) used / max > 0.9) {
alertService.send(new Alert(
"内存使用率过高",
String.format("内存池 %s 使用率: %.2f%%",
pool.getName(), (double) used / max * 100)
));
}
// 检查是否有内存池已满
if (pool.isCollectionUsageThresholdSupported()) {
MemoryUsage collectionUsage = pool.getCollectionUsage();
if (collectionUsage != null &&
collectionUsage.getUsed() > collectionUsage.getMax() * 0.9) {
alertService.send(new Alert(
"GC后内存仍高",
String.format("内存池 %s GC后使用率仍高", pool.getName())
));
}
}
}
}
}
}
GC算法详解
// GC配置与监控
@Component
public class GCConfigAndMonitor {
// G1 GC配置建议
public String getG1GCConfig() {
return """
-XX:+UseG1GC
-XX:MaxGCPauseMillis=200
-XX:G1HeapRegionSize=16m
-XX:InitiatingHeapOccupancyPercent=45
-XX:G1ReservePercent=10
-XX:G1NewSizePercent=5
-XX:G1MaxNewSizePercent=60
-XX:+ParallelRefProcEnabled
-XX:ParallelGCThreads=8
-XX:ConcGCThreads=4
""";
}
// ZGC配置建议
public String getZGCConfig() {
return """
-XX:+UseZGC
-XX:+ZGenerational
-XX:SoftMaxHeapSize=8G
-XX:ZUncommitDelay=300
-XX:+UnlockExperimentalVMOptions
""";
}
// Shenandoah配置建议
public String getShenandoahConfig() {
return """
-XX:+UseShenandoahGC
-XX:ShenandoahGCHeuristics=compact
-XX:ShenandoahMinFreeThreshold=10
-XX:ShenandoahGuaranteedGCInterval=300000
""";
}
}
// GC日志分析
@Component
public class GCLogAnalyzer {
public GCAnalysis analyze(String logFilePath) throws IOException {
List<GCEvent> events = new ArrayList<>();
try (BufferedReader reader = Files.newBufferedReader(
Path.of(logFilePath))) {
String line;
while ((line = reader.readLine()) != null) {
if (line.contains("GC")) {
GCEvent event = parseGCEvent(line);
if (event != null) {
events.add(event);
}
}
}
}
// 分析GC模式
return analyzePattern(events);
}
private GCAnalysis analyzePattern(List<GCEvent> events) {
GCAnalysis analysis = new GCAnalysis();
// 计算GC频率
long totalTime = events.stream()
.mapToLong(GCEvent::getDuration)
.sum();
double avgPause = events.stream()
.mapToLong(GCEvent::getPauseTime)
.average()
.orElse(0);
long maxPause = events.stream()
.mapToLong(GCEvent::getPauseTime)
.max()
.orElse(0);
analysis.setTotalGCTime(totalTime);
analysis.setAvgPause(avgPause);
analysis.setMaxPause(maxPause);
analysis.setGCFrequency(events.size());
// 检测问题
if (maxPause > 200) {
analysis.addIssue("最大GC暂停时间过长: " + maxPause + "ms");
}
if (events.size() > 100) {
analysis.addIssue("GC频率过高,可能存在内存压力");
}
return analysis;
}
}
JIT编译优化
// JIT监控与优化
@Component
public class JITOptimizer {
private final CompilationMXBean compilationBean;
public JITStats getJITStats() {
return JITStats.builder()
.totalCompilationTime(compilationBean.getTotalCompilationTime())
.totalCompiledMethods(compilationBean.getTotalCompilationTime())
.build();
}
// 常用JIT优化参数
public String getOptimizationFlags() {
return """
-XX:+TieredCompilation
-XX:TieredStopAtLevel=4
-XX:CompileThreshold=10000
-XX:OnStackReplacePercentage=140
-XX:InterpreterProfilePercentage=33
-XX:+UseCodeCacheExpansion
-XX:ReservedCodeCacheSize=256m
-XX:InitialCodeCacheSize=128m
""";
}
// 内联优化
public String getInliningFlags() {
return """
-XX:+UnlockDiagnosticVMOptions
-XX:+PrintInlining
-XX:MaxInlineSize=35
-XX:FreqInlineSize=325
-XX:MaxInlineLevel=9
-XX:MaxRecursiveInlineLevel=3
""";
}
}
JVM性能调优实战
# JVM调优配置
jvm:
memory:
# 堆内存配置
heap:
min: "4g"
max: "8g"
young_gen: "2g"
old_gen: "6g"
# 非堆内存
non_heap:
metaspace: "256m"
code_cache: "256m"
# 线程栈
thread_stack: "512k"
# 直接内存
direct_memory: "1g"
gc:
# G1 GC配置
g1:
enabled: true
max_pause_millis: 200
heap_region_size: "16m"
initiating_occupancy_percent: 45
parallel_gc_threads: 8
conc_gc_threads: 4
# ZGC配置
zgc:
enabled: false
max_heap_size: "16g"
soft_max_heap_size: "8g"
jit:
tiered_compilation: true
compile_threshold: 10000
code_cache_size: "256m"
diagnostics:
heap_dump_on_oome: true
heap_dump_path: "/tmp/heapdump.hprof"
gc_log: true
gc_log_path: "/var/log/gc.log"
gc_log_options: "-Xlog:gc*:file=/var/log/gc.log:time,uptime,level,tags"
JVM架构优化通过理解内存模型、选择合适的GC算法和JIT调优,显著提升Java应用的性能和稳定性。