1. 内存运维监控概述

内存是服务器性能的关键指标,内存不足会导致系统性能下降、OOM错误等问题。本文将详细介绍内存监控、内存泄漏检测、GC优化和内存调优的完整解决方案,帮助运维人员有效管理内存资源。

1.1 核心挑战

  1. 内存使用率监控: 实时监控内存使用情况
  2. 内存泄漏检测: 及时发现和定位内存泄漏
  3. GC性能优化: 优化垃圾回收性能
  4. 内存调优: 优化内存分配和回收策略
  5. OOM预防: 预防内存溢出问题

1.2 技术架构

1
2
3
4
5
内存监控 → 数据采集 → 数据分析 → 告警通知 → 自动优化
↓ ↓ ↓ ↓ ↓
JVM内存 → 监控代理 → 数据存储 → 告警引擎 → 调优脚本
↓ ↓ ↓ ↓ ↓
系统内存 → 性能分析 → 趋势分析 → 通知推送 → 参数调整

2. 内存监控系统

2.1 Maven依赖配置

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
<!-- pom.xml -->
<dependencies>
<!-- Spring Boot Web -->
<dependency>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-starter-web</artifactId>
</dependency>

<!-- Spring Boot Data Redis -->
<dependency>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-starter-data-redis</artifactId>
</dependency>

<!-- Micrometer监控 -->
<dependency>
<groupId>io.micrometer</groupId>
<artifactId>micrometer-registry-prometheus</artifactId>
</dependency>

<!-- OSHI系统信息 -->
<dependency>
<groupId>com.github.oshi</groupId>
<artifactId>oshi-core</artifactId>
<version>6.4.0</version>
</dependency>

<!-- MyBatis Plus -->
<dependency>
<groupId>com.baomidou</groupId>
<artifactId>mybatis-plus-boot-starter</artifactId>
<version>3.5.2</version>
</dependency>
</dependencies>

2.2 应用配置

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
# application.yml
server:
port: 8080

spring:
redis:
host: localhost
port: 6379
database: 0

# 内存监控配置
memory-monitor:
collection-interval: 5000 # 采集间隔(毫秒)
alert-threshold: 85 # 告警阈值(%)
critical-threshold: 95 # 严重告警阈值(%)
gc-monitor-enabled: true # 启用GC监控
heap-dump-enabled: true # 启用堆转储

3. 内存监控服务

3.1 内存监控实体类

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
/**
* 内存监控数据实体类
*/
@Data
@TableName("memory_monitor_data")
public class MemoryMonitorData {

@TableId(type = IdType.AUTO)
private Long id; // 主键ID

private String hostname; // 主机名

private String ip; // IP地址

private Long totalMemory; // 总内存

private Long usedMemory; // 已使用内存

private Long freeMemory; // 空闲内存

private Double memoryUsage; // 内存使用率

private Long heapMemoryUsed; // 堆内存已使用

private Long heapMemoryMax; // 堆内存最大值

private Long nonHeapMemoryUsed; // 非堆内存已使用

private Long nonHeapMemoryMax; // 非堆内存最大值

private Long gcCount; // GC次数

private Long gcTime; // GC时间

private Date collectTime; // 采集时间

private Date createTime; // 创建时间
}

/**
* GC监控数据实体类
*/
@Data
@TableName("gc_monitor_data")
public class GcMonitorData {

@TableId(type = IdType.AUTO)
private Long id; // 主键ID

private String hostname; // 主机名

private String gcName; // GC名称

private Long collectionCount; // 收集次数

private Long collectionTime; // 收集时间

private String memoryPoolNames; // 内存池名称

private Date collectTime; // 采集时间
}

3.2 内存监控服务

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
168
169
170
171
172
173
174
175
176
177
178
179
180
181
182
183
184
185
186
187
188
189
190
191
192
193
194
195
196
197
198
199
200
201
202
203
204
205
206
207
208
209
210
211
212
213
214
215
216
217
218
219
220
221
222
223
224
225
226
227
228
229
230
231
232
233
234
235
236
237
238
239
240
241
242
243
244
245
246
247
248
249
250
251
252
253
254
255
256
257
258
259
260
261
262
263
264
265
266
267
268
269
270
271
272
273
274
275
276
277
278
279
280
281
282
283
284
285
286
287
288
289
290
291
292
293
/**
* 内存监控服务
* 负责内存数据的采集、存储和分析
*/
@Service
public class MemoryMonitorService {

@Autowired
private MemoryMonitorDataMapper memoryMonitorDataMapper;

@Autowired
private GcMonitorDataMapper gcMonitorDataMapper;

@Autowired
private RedisTemplate<String, Object> redisTemplate;

@Autowired
private AlertService alertService;

/**
* 采集内存数据
* 定期采集内存使用情况
*/
@Scheduled(fixedRate = 5000) // 每5秒执行一次
public void collectMemoryData() {
try {
// 1. 获取系统内存信息
MemoryInfo systemMemory = getSystemMemoryInfo();

// 2. 获取JVM内存信息
MemoryInfo jvmMemory = getJvmMemoryInfo();

// 3. 创建内存监控数据
MemoryMonitorData memoryData = createMemoryMonitorData(systemMemory, jvmMemory);

// 4. 保存到数据库
memoryMonitorDataMapper.insert(memoryData);

// 5. 更新缓存
updateMemoryCache(memoryData);

// 6. 检查告警条件
checkMemoryAlert(memoryData);

log.debug("采集内存数据: hostname={}, memoryUsage={}%",
memoryData.getHostname(), memoryData.getMemoryUsage());

} catch (Exception e) {
log.error("采集内存数据失败: {}", e.getMessage(), e);
}
}

/**
* 获取系统内存信息
*/
private MemoryInfo getSystemMemoryInfo() {
MemoryInfo memoryInfo = new MemoryInfo();

try {
// 使用OSHI获取系统内存信息
SystemInfo systemInfo = new SystemInfo();
HardwareAbstractionLayer hal = systemInfo.getHardware();
GlobalMemory memory = hal.getMemory();

memoryInfo.setTotal(memory.getTotal());
memoryInfo.setAvailable(memory.getAvailable());
memoryInfo.setUsed(memory.getTotal() - memory.getAvailable());
memoryInfo.setUsage((double) memoryInfo.getUsed() / memoryInfo.getTotal() * 100);

} catch (Exception e) {
log.error("获取系统内存信息失败: {}", e.getMessage(), e);
}

return memoryInfo;
}

/**
* 获取JVM内存信息
*/
private MemoryInfo getJvmMemoryInfo() {
MemoryInfo memoryInfo = new MemoryInfo();

try {
// 获取堆内存信息
MemoryMXBean memoryBean = ManagementFactory.getMemoryMXBean();
MemoryUsage heapUsage = memoryBean.getHeapMemoryUsage();
MemoryUsage nonHeapUsage = memoryBean.getNonHeapMemoryUsage();

memoryInfo.setHeapUsed(heapUsage.getUsed());
memoryInfo.setHeapMax(heapUsage.getMax());
memoryInfo.setNonHeapUsed(nonHeapUsage.getUsed());
memoryInfo.setNonHeapMax(nonHeapUsage.getMax());

// 获取GC信息
List<GarbageCollectorMXBean> gcBeans = ManagementFactory.getGarbageCollectorMXBeans();
long totalGcCount = 0;
long totalGcTime = 0;

for (GarbageCollectorMXBean gcBean : gcBeans) {
totalGcCount += gcBean.getCollectionCount();
totalGcTime += gcBean.getCollectionTime();
}

memoryInfo.setGcCount(totalGcCount);
memoryInfo.setGcTime(totalGcTime);

} catch (Exception e) {
log.error("获取JVM内存信息失败: {}", e.getMessage(), e);
}

return memoryInfo;
}

/**
* 创建内存监控数据
*/
private MemoryMonitorData createMemoryMonitorData(MemoryInfo systemMemory, MemoryInfo jvmMemory) {
MemoryMonitorData memoryData = new MemoryMonitorData();

// 设置基本信息
memoryData.setHostname(getHostname());
memoryData.setIp(getLocalIpAddress());
memoryData.setCollectTime(new Date());
memoryData.setCreateTime(new Date());

// 设置系统内存信息
memoryData.setTotalMemory(systemMemory.getTotal());
memoryData.setUsedMemory(systemMemory.getUsed());
memoryData.setFreeMemory(systemMemory.getAvailable());
memoryData.setMemoryUsage(systemMemory.getUsage());

// 设置JVM内存信息
memoryData.setHeapMemoryUsed(jvmMemory.getHeapUsed());
memoryData.setHeapMemoryMax(jvmMemory.getHeapMax());
memoryData.setNonHeapMemoryUsed(jvmMemory.getNonHeapUsed());
memoryData.setNonHeapMemoryMax(jvmMemory.getNonHeapMax());

// 设置GC信息
memoryData.setGcCount(jvmMemory.getGcCount());
memoryData.setGcTime(jvmMemory.getGcTime());

return memoryData;
}

/**
* 更新内存缓存
*/
private void updateMemoryCache(MemoryMonitorData memoryData) {
try {
String cacheKey = "memory:realtime:" + memoryData.getHostname();
redisTemplate.opsForValue().set(cacheKey, memoryData, Duration.ofMinutes(5));

// 更新历史数据缓存
String historyKey = "memory:history:" + memoryData.getHostname();
redisTemplate.opsForList().leftPush(historyKey, memoryData);
redisTemplate.opsForList().trim(historyKey, 0, 99);
redisTemplate.expire(historyKey, Duration.ofHours(1));

} catch (Exception e) {
log.warn("更新内存缓存失败: {}", e.getMessage());
}
}

/**
* 检查内存告警
*/
private void checkMemoryAlert(MemoryMonitorData memoryData) {
try {
String alertType = null;
String alertLevel = null;
String alertMessage = null;

// 检查内存使用率告警
if (memoryData.getMemoryUsage() >= 95) {
alertType = "MEMORY_CRITICAL";
alertLevel = "CRITICAL";
alertMessage = String.format("内存使用率过高: %.2f%%", memoryData.getMemoryUsage());
} else if (memoryData.getMemoryUsage() >= 85) {
alertType = "MEMORY_HIGH";
alertLevel = "WARNING";
alertMessage = String.format("内存使用率较高: %.2f%%", memoryData.getMemoryUsage());
}

// 检查堆内存告警
if (memoryData.getHeapMemoryMax() > 0) {
double heapUsage = (double) memoryData.getHeapMemoryUsed() / memoryData.getHeapMemoryMax() * 100;
if (heapUsage >= 90) {
alertType = "HEAP_MEMORY_HIGH";
alertLevel = "WARNING";
alertMessage = String.format("堆内存使用率过高: %.2f%%", heapUsage);
}
}

// 发送告警
if (alertType != null) {
sendMemoryAlert(memoryData, alertType, alertLevel, alertMessage);
}

} catch (Exception e) {
log.error("检查内存告警失败: {}", e.getMessage(), e);
}
}

/**
* 发送内存告警
*/
private void sendMemoryAlert(MemoryMonitorData memoryData, String alertType, String alertLevel, String alertMessage) {
try {
// 检查是否已经发送过相同告警
String alertKey = "memory:alert:" + memoryData.getHostname() + ":" + alertType;
Boolean hasAlert = redisTemplate.hasKey(alertKey);

if (hasAlert == null || !hasAlert) {
// 创建告警记录
MemoryAlertRecord alertRecord = new MemoryAlertRecord();
alertRecord.setHostname(memoryData.getHostname());
alertRecord.setIp(memoryData.getIp());
alertRecord.setAlertType(alertType);
alertRecord.setAlertLevel(alertLevel);
alertRecord.setMemoryUsage(memoryData.getMemoryUsage());
alertRecord.setAlertMessage(alertMessage);
alertRecord.setAlertStatus("ACTIVE");
alertRecord.setAlertTime(new Date());

// 发送告警通知
alertService.sendMemoryAlert(alertRecord);

// 设置告警缓存
redisTemplate.opsForValue().set(alertKey, "1", Duration.ofMinutes(5));

log.warn("发送内存告警: hostname={}, type={}, level={}",
memoryData.getHostname(), alertType, alertLevel);
}

} catch (Exception e) {
log.error("发送内存告警失败: {}", e.getMessage(), e);
}
}

/**
* 获取实时内存数据
*/
public MemoryMonitorData getRealTimeMemoryData(String hostname) {
String cacheKey = "memory:realtime:" + hostname;
return (MemoryMonitorData) redisTemplate.opsForValue().get(cacheKey);
}

/**
* 获取内存历史数据
*/
public List<MemoryMonitorData> getMemoryHistoryData(String hostname, Date startTime, Date endTime) {
return memoryMonitorDataMapper.selectByHostnameAndTimeRange(hostname, startTime, endTime);
}

/**
* 获取主机名
*/
private String getHostname() {
try {
return InetAddress.getLocalHost().getHostName();
} catch (UnknownHostException e) {
return "unknown";
}
}

/**
* 获取本地IP地址
*/
private String getLocalIpAddress() {
try {
return InetAddress.getLocalHost().getHostAddress();
} catch (UnknownHostException e) {
return "127.0.0.1";
}
}
}

/**
* 内存信息实体类
*/
@Data
public class MemoryInfo {
private Long total; // 总内存
private Long used; // 已使用内存
private Long available; // 可用内存
private Double usage; // 内存使用率
private Long heapUsed; // 堆内存已使用
private Long heapMax; // 堆内存最大值
private Long nonHeapUsed; // 非堆内存已使用
private Long nonHeapMax; // 非堆内存最大值
private Long gcCount; // GC次数
private Long gcTime; // GC时间
}

4. GC监控服务

4.1 GC监控服务

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
168
169
170
171
172
173
174
175
176
177
178
179
180
181
182
183
184
185
186
187
188
189
190
191
192
193
194
195
196
197
198
199
200
201
202
203
204
205
206
207
208
209
210
211
212
/**
* GC监控服务
* 负责GC数据的采集和分析
*/
@Service
public class GcMonitorService {

@Autowired
private GcMonitorDataMapper gcMonitorDataMapper;

@Autowired
private RedisTemplate<String, Object> redisTemplate;

@Autowired
private AlertService alertService;

/**
* 采集GC数据
* 定期采集GC信息
*/
@Scheduled(fixedRate = 10000) // 每10秒执行一次
public void collectGcData() {
try {
// 1. 获取所有GC信息
List<GarbageCollectorMXBean> gcBeans = ManagementFactory.getGarbageCollectorMXBeans();

// 2. 采集每个GC的数据
for (GarbageCollectorMXBean gcBean : gcBeans) {
collectGcBeanData(gcBean);
}

// 3. 分析GC性能
analyzeGcPerformance();

} catch (Exception e) {
log.error("采集GC数据失败: {}", e.getMessage(), e);
}
}

/**
* 采集单个GC数据
*/
private void collectGcBeanData(GarbageCollectorMXBean gcBean) {
try {
// 1. 创建GC监控数据
GcMonitorData gcData = new GcMonitorData();
gcData.setHostname(getHostname());
gcData.setGcName(gcBean.getName());
gcData.setCollectionCount(gcBean.getCollectionCount());
gcData.setCollectionTime(gcBean.getCollectionTime());
gcData.setMemoryPoolNames(String.join(",", gcBean.getMemoryPoolNames()));
gcData.setCollectTime(new Date());

// 2. 保存到数据库
gcMonitorDataMapper.insert(gcData);

// 3. 更新缓存
updateGcCache(gcData);

// 4. 检查GC告警
checkGcAlert(gcData);

log.debug("采集GC数据: gcName={}, count={}, time={}ms",
gcData.getGcName(), gcData.getCollectionCount(), gcData.getCollectionTime());

} catch (Exception e) {
log.error("采集GC数据失败: gcName={}, error={}",
gcBean.getName(), e.getMessage(), e);
}
}

/**
* 更新GC缓存
*/
private void updateGcCache(GcMonitorData gcData) {
try {
String cacheKey = "gc:realtime:" + gcData.getHostname() + ":" + gcData.getGcName();
redisTemplate.opsForValue().set(cacheKey, gcData, Duration.ofMinutes(5));

} catch (Exception e) {
log.warn("更新GC缓存失败: {}", e.getMessage());
}
}

/**
* 检查GC告警
*/
private void checkGcAlert(GcMonitorData gcData) {
try {
// 检查GC频率告警
if (gcData.getCollectionTime() > 1000) { // GC时间超过1秒
sendGcAlert(gcData, "GC_SLOW", "WARNING",
String.format("GC执行时间过长: %dms", gcData.getCollectionTime()));
}

// 检查GC频率告警
String frequencyKey = "gc:frequency:" + gcData.getHostname() + ":" + gcData.getGcName();
Long frequency = redisTemplate.opsForValue().increment(frequencyKey);
redisTemplate.expire(frequencyKey, Duration.ofMinutes(1));

if (frequency > 10) { // 1分钟内GC次数超过10次
sendGcAlert(gcData, "GC_FREQUENT", "WARNING",
String.format("GC频率过高: %d次/分钟", frequency));
}

} catch (Exception e) {
log.error("检查GC告警失败: {}", e.getMessage(), e);
}
}

/**
* 发送GC告警
*/
private void sendGcAlert(GcMonitorData gcData, String alertType, String alertLevel, String alertMessage) {
try {
String alertKey = "gc:alert:" + gcData.getHostname() + ":" + alertType;
Boolean hasAlert = redisTemplate.hasKey(alertKey);

if (hasAlert == null || !hasAlert) {
// 创建告警记录
GcAlertRecord alertRecord = new GcAlertRecord();
alertRecord.setHostname(gcData.getHostname());
alertRecord.setGcName(gcData.getGcName());
alertRecord.setAlertType(alertType);
alertRecord.setAlertLevel(alertLevel);
alertRecord.setAlertMessage(alertMessage);
alertRecord.setAlertStatus("ACTIVE");
alertRecord.setAlertTime(new Date());

// 发送告警通知
alertService.sendGcAlert(alertRecord);

// 设置告警缓存
redisTemplate.opsForValue().set(alertKey, "1", Duration.ofMinutes(5));

log.warn("发送GC告警: hostname={}, gcName={}, type={}",
gcData.getHostname(), gcData.getGcName(), alertType);
}

} catch (Exception e) {
log.error("发送GC告警失败: {}", e.getMessage(), e);
}
}

/**
* 分析GC性能
*/
private void analyzeGcPerformance() {
try {
// 获取所有GC信息
List<GarbageCollectorMXBean> gcBeans = ManagementFactory.getGarbageCollectorMXBeans();

long totalGcTime = 0;
long totalGcCount = 0;

for (GarbageCollectorMXBean gcBean : gcBeans) {
totalGcTime += gcBean.getCollectionTime();
totalGcCount += gcBean.getCollectionCount();
}

// 计算GC性能指标
double avgGcTime = totalGcCount > 0 ? (double) totalGcTime / totalGcCount : 0;
double gcFrequency = totalGcCount / 60.0; // 每分钟GC次数

// 更新GC性能统计
updateGcPerformanceStats(avgGcTime, gcFrequency);

log.debug("GC性能分析: avgTime={}ms, frequency={}次/分钟", avgGcTime, gcFrequency);

} catch (Exception e) {
log.error("分析GC性能失败: {}", e.getMessage(), e);
}
}

/**
* 更新GC性能统计
*/
private void updateGcPerformanceStats(double avgGcTime, double gcFrequency) {
try {
String statsKey = "gc:performance:" + getHostname();

Map<String, Object> stats = new HashMap<>();
stats.put("avgGcTime", avgGcTime);
stats.put("gcFrequency", gcFrequency);
stats.put("lastUpdateTime", System.currentTimeMillis());

redisTemplate.opsForValue().set(statsKey, stats, Duration.ofMinutes(10));

} catch (Exception e) {
log.warn("更新GC性能统计失败: {}", e.getMessage());
}
}

/**
* 获取GC性能统计
*/
public Map<String, Object> getGcPerformanceStats(String hostname) {
String statsKey = "gc:performance:" + hostname;
return (Map<String, Object>) redisTemplate.opsForValue().get(statsKey);
}

/**
* 获取主机名
*/
private String getHostname() {
try {
return InetAddress.getLocalHost().getHostName();
} catch (UnknownHostException e) {
return "unknown";
}
}
}

5. 内存优化服务

5.1 内存优化服务

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
168
169
170
171
172
173
174
175
176
177
178
179
180
181
182
183
184
185
186
187
188
189
190
191
192
193
194
195
196
197
198
199
200
201
202
203
204
205
206
207
208
209
210
211
212
213
214
215
216
217
218
219
220
221
222
223
224
225
226
227
228
229
230
231
232
233
234
235
236
237
238
239
240
241
242
243
244
245
246
247
248
249
250
251
252
253
254
255
256
257
258
259
260
261
262
263
264
265
266
267
268
269
270
271
272
273
274
275
276
277
278
279
280
281
282
283
284
285
286
287
288
289
290
291
292
293
294
295
296
297
298
299
300
301
302
303
304
305
306
307
308
309
310
311
312
313
314
315
316
317
318
319
320
321
322
323
324
325
326
327
328
329
330
331
332
333
334
335
336
337
338
339
340
341
342
343
344
345
346
347
348
349
350
351
352
353
354
355
356
357
358
359
360
361
362
363
364
365
366
367
368
369
370
371
372
373
374
375
376
377
378
379
380
381
382
383
384
385
386
387
388
389
390
391
392
393
394
395
396
397
398
399
400
401
402
403
404
405
406
407
/**
* 内存优化服务
* 提供内存优化和调优功能
*/
@Service
public class MemoryOptimizationService {

@Autowired
private MemoryMonitorService memoryMonitorService;

@Autowired
private GcMonitorService gcMonitorService;

@Autowired
private AlertService alertService;

/**
* 自动内存优化
* 根据内存使用情况自动进行优化
*/
@Scheduled(fixedRate = 60000) // 每1分钟执行一次
public void autoOptimizeMemory() {
try {
String hostname = getHostname();
MemoryMonitorData memoryData = memoryMonitorService.getRealTimeMemoryData(hostname);

if (memoryData == null) {
return;
}

// 检查内存使用率
if (memoryData.getMemoryUsage() > 90) {
// 内存使用率过高,执行优化策略
executeHighMemoryOptimization(memoryData);
} else if (memoryData.getMemoryUsage() > 80) {
// 内存使用率较高,执行预防性优化
executePreventiveOptimization(memoryData);
}

} catch (Exception e) {
log.error("自动内存优化失败: {}", e.getMessage(), e);
}
}

/**
* 执行高内存使用率优化
*/
private void executeHighMemoryOptimization(MemoryMonitorData memoryData) {
log.warn("执行高内存使用率优化: memoryUsage={}%", memoryData.getMemoryUsage());

try {
// 1. 强制GC
forceGarbageCollection();

// 2. 清理缓存
cleanupCaches();

// 3. 调整JVM参数
suggestJvmMemoryOptimization();

// 4. 生成堆转储
if (memoryData.getMemoryUsage() > 95) {
generateHeapDump();
}

// 5. 发送优化通知
sendOptimizationNotification(memoryData, "HIGH_MEMORY_OPTIMIZATION");

} catch (Exception e) {
log.error("执行高内存使用率优化失败: {}", e.getMessage(), e);
}
}

/**
* 执行预防性优化
*/
private void executePreventiveOptimization(MemoryMonitorData memoryData) {
log.info("执行预防性内存优化: memoryUsage={}%", memoryData.getMemoryUsage());

try {
// 1. 优化缓存策略
optimizeCacheStrategy();

// 2. 调整内存分配
adjustMemoryAllocation();

// 3. 优化GC策略
optimizeGcStrategy();

// 4. 发送优化通知
sendOptimizationNotification(memoryData, "PREVENTIVE_OPTIMIZATION");

} catch (Exception e) {
log.error("执行预防性优化失败: {}", e.getMessage(), e);
}
}

/**
* 强制垃圾回收
*/
private void forceGarbageCollection() {
log.info("执行强制垃圾回收");

try {
// 建议JVM执行GC
System.gc();

// 等待GC完成
Thread.sleep(1000);

log.info("强制垃圾回收完成");

} catch (Exception e) {
log.error("强制垃圾回收失败: {}", e.getMessage(), e);
}
}

/**
* 清理缓存
*/
private void cleanupCaches() {
log.info("清理系统缓存");

try {
// 清理应用缓存
cleanupApplicationCaches();

// 清理系统缓存
cleanupSystemCaches();

} catch (Exception e) {
log.error("清理缓存失败: {}", e.getMessage(), e);
}
}

/**
* 清理应用缓存
*/
private void cleanupApplicationCaches() {
// 实现应用缓存清理逻辑
log.info("清理应用缓存");
}

/**
* 清理系统缓存
*/
private void cleanupSystemCaches() {
// 实现系统缓存清理逻辑
log.info("清理系统缓存");
}

/**
* 建议JVM内存优化
*/
private void suggestJvmMemoryOptimization() {
log.info("建议JVM内存优化");

try {
// 获取当前JVM参数
RuntimeMXBean runtimeBean = ManagementFactory.getRuntimeMXBean();
List<String> jvmArgs = runtimeBean.getInputArguments();

// 分析内存参数
analyzeMemoryParameters(jvmArgs);

// 提供优化建议
provideMemoryOptimizationSuggestions();

} catch (Exception e) {
log.error("建议JVM内存优化失败: {}", e.getMessage(), e);
}
}

/**
* 分析内存参数
*/
private void analyzeMemoryParameters(List<String> jvmArgs) {
Map<String, String> memoryParams = new HashMap<>();

for (String arg : jvmArgs) {
if (arg.startsWith("-Xms") || arg.startsWith("-Xmx") ||
arg.startsWith("-XX:NewRatio") || arg.startsWith("-XX:SurvivorRatio")) {
String[] parts = arg.split("=", 2);
if (parts.length == 2) {
memoryParams.put(parts[0], parts[1]);
} else {
memoryParams.put(parts[0], "true");
}
}
}

log.info("当前内存参数: {}", memoryParams);
}

/**
* 提供内存优化建议
*/
private void provideMemoryOptimizationSuggestions() {
List<String> suggestions = new ArrayList<>();

// 堆内存建议
suggestions.add("建议设置合适的堆内存大小: -Xms2g -Xmx2g");

// 新生代建议
suggestions.add("建议设置合适的新生代比例: -XX:NewRatio=1");

// GC建议
suggestions.add("建议使用G1垃圾收集器: -XX:+UseG1GC");

// 内存建议
suggestions.add("建议启用压缩指针: -XX:+UseCompressedOops");

log.info("内存优化建议: {}", suggestions);
}

/**
* 生成堆转储
*/
private void generateHeapDump() {
log.warn("生成堆转储文件");

try {
// 获取堆转储信息
MemoryMXBean memoryBean = ManagementFactory.getMemoryMXBean();
MemoryUsage heapUsage = memoryBean.getHeapMemoryUsage();

// 生成堆转储文件路径
String dumpPath = "/tmp/heapdump_" + System.currentTimeMillis() + ".hprof";

// 生成堆转储
MBeanServer server = ManagementFactory.getPlatformMBeanServer();
HotSpotDiagnosticMXBean hotspotMBean = ManagementFactory.newPlatformMXBeanProxy(
server, "com.sun.management:type=HotSpotDiagnostic", HotSpotDiagnosticMXBean.class);

hotspotMBean.dumpHeap(dumpPath, true);

log.warn("堆转储文件生成完成: {}", dumpPath);

// 发送堆转储通知
sendHeapDumpNotification(dumpPath);

} catch (Exception e) {
log.error("生成堆转储失败: {}", e.getMessage(), e);
}
}

/**
* 发送堆转储通知
*/
private void sendHeapDumpNotification(String dumpPath) {
try {
AlertMessage alert = new AlertMessage();
alert.setType("HEAP_DUMP");
alert.setLevel("WARNING");
alert.setMessage("内存使用率过高,已生成堆转储文件: " + dumpPath);
alert.setTimestamp(new Date());

alertService.sendAlert(alert);

} catch (Exception e) {
log.error("发送堆转储通知失败: {}", e.getMessage(), e);
}
}

/**
* 优化缓存策略
*/
private void optimizeCacheStrategy() {
log.info("优化缓存策略");

try {
// 调整缓存大小
adjustCacheSize();

// 优化缓存过期策略
optimizeCacheExpiration();

} catch (Exception e) {
log.error("优化缓存策略失败: {}", e.getMessage(), e);
}
}

/**
* 调整缓存大小
*/
private void adjustCacheSize() {
// 实现缓存大小调整逻辑
log.info("调整缓存大小");
}

/**
* 优化缓存过期策略
*/
private void optimizeCacheExpiration() {
// 实现缓存过期策略优化逻辑
log.info("优化缓存过期策略");
}

/**
* 调整内存分配
*/
private void adjustMemoryAllocation() {
log.info("调整内存分配");

try {
// 调整线程池大小
adjustThreadPoolSize();

// 调整连接池大小
adjustConnectionPoolSize();

} catch (Exception e) {
log.error("调整内存分配失败: {}", e.getMessage(), e);
}
}

/**
* 调整线程池大小
*/
private void adjustThreadPoolSize() {
// 实现线程池大小调整逻辑
log.info("调整线程池大小");
}

/**
* 调整连接池大小
*/
private void adjustConnectionPoolSize() {
// 实现连接池大小调整逻辑
log.info("调整连接池大小");
}

/**
* 优化GC策略
*/
private void optimizeGcStrategy() {
log.info("优化GC策略");

try {
// 分析GC性能
analyzeGcPerformance();

// 提供GC优化建议
provideGcOptimizationSuggestions();

} catch (Exception e) {
log.error("优化GC策略失败: {}", e.getMessage(), e);
}
}

/**
* 分析GC性能
*/
private void analyzeGcPerformance() {
try {
Map<String, Object> gcStats = gcMonitorService.getGcPerformanceStats(getHostname());
if (gcStats != null) {
log.info("GC性能分析: {}", gcStats);
}
} catch (Exception e) {
log.error("分析GC性能失败: {}", e.getMessage(), e);
}
}

/**
* 提供GC优化建议
*/
private void provideGcOptimizationSuggestions() {
List<String> suggestions = new ArrayList<>();

suggestions.add("建议使用G1垃圾收集器: -XX:+UseG1GC");
suggestions.add("建议设置最大GC暂停时间: -XX:MaxGCPauseMillis=200");
suggestions.add("建议启用字符串去重: -XX:+UseStringDeduplication");

log.info("GC优化建议: {}", suggestions);
}

/**
* 发送优化通知
*/
private void sendOptimizationNotification(MemoryMonitorData memoryData, String optimizationType) {
try {
AlertMessage alert = new AlertMessage();
alert.setType("MEMORY_OPTIMIZATION");
alert.setLevel("INFO");
alert.setMessage(String.format("内存优化完成: 类型=%s, 内存使用率=%.2f%%",
optimizationType, memoryData.getMemoryUsage()));
alert.setTimestamp(new Date());

alertService.sendAlert(alert);

} catch (Exception e) {
log.error("发送优化通知失败: {}", e.getMessage(), e);
}
}

/**
* 获取主机名
*/
private String getHostname() {
try {
return InetAddress.getLocalHost().getHostName();
} catch (UnknownHostException e) {
return "unknown";
}
}
}

6. 总结

本文详细介绍了内存运维监控与优化的完整解决方案,包括:

6.1 核心技术点

  1. 内存监控: 实时监控内存使用率、堆内存、非堆内存
  2. GC监控: 监控GC性能、GC频率、GC时间
  3. 内存优化: 自动内存优化、缓存清理、JVM调优
  4. 告警通知: 多级告警、智能通知
  5. 性能分析: 内存趋势分析、GC性能分析

6.2 架构优势

  1. 实时监控: 5秒间隔的实时内存数据采集
  2. 智能告警: 基于阈值的智能告警机制
  3. 自动优化: 自动化的内存性能优化
  4. 多维度分析: 内存使用率、GC性能等多维度分析

6.3 最佳实践

  1. 监控策略: 设置合理的内存监控阈值
  2. 优化策略: 根据内存使用情况执行针对性优化
  3. GC优化: 选择合适的GC策略和参数
  4. 预防措施: 提前预防内存泄漏和OOM问题

通过以上架构设计,可以构建完善的内存运维监控系统,实现内存资源的有效管理和性能优化。