Java服务内存优化指南
1. JVM内存配置优化
堆内存设置
# 合理设置堆大小
-Xms2g -Xmx2g # 固定堆大小,避免动态调整开销
-XX:NewRatio=3 # 老年代:新生代 = 3:1
-XX:SurvivorRatio=8 # Eden:S0:S1 = 8:1:1
元空间优化
-XX:MetaspaceSize=128m # 初始元空间大小
-XX:MaxMetaspaceSize=256m # 最大元空间大小
禁用不必要的功能
-XX:+UseCompressedOops # 使用压缩指针(64位JVM)
-XX:-TieredCompilation # 关闭分层编译(减少内存占用)
-XX:+UseStringDeduplication # 字符串去重
2. 垃圾回收器选择
G1 GC配置(推荐)
-XX:+UseG1GC
-XX:MaxGCPauseMillis=200
-XX:G1HeapRegionSize=16m
-XX:G1ReservePercent=15
-XX:InitiatingHeapOccupancyPercent=45
ZGC配置(JDK 11+)
-XX:+UseZGC
-XX:ZCollectionInterval=10
-XX:ZAllocationSpikeTolerance=5.0
3. 应用级内存优化
对象池化
// 使用对象池减少创建开销
public class ObjectPool<T> {
private final Queue<T> pool = new ConcurrentLinkedQueue<>();
private final Supplier<T> factory;
public T borrow() {
T obj = pool.poll();
return obj != null ? obj : factory.get();
}
public void release(T obj) {
if (pool.size() < MAX_POOL_SIZE) {
pool.offer(obj);
}
}
}
缓存优化
// 使用LRU缓存并设置合理大小
@Configuration
public class CacheConfig {
@Bean
public Cache<String, Object> cache() {
return Caffeine.newBuilder()
.maximumSize(1000) // 限制缓存大小
.expireAfterWrite(10, TimeUnit.MINUTES)
.recordStats()
.build();
}
}
4. 连接池优化
数据库连接池
# HikariCP配置
spring:
datasource:
hikari:
maximum-pool-size: 20
minimum-idle: 5
connection-timeout: 30000
idle-timeout: 600000
max-lifetime: 1800000
HTTP客户端连接池
@Bean
public CloseableHttpClient httpClient() {
return HttpClients.custom()
.setMaxConnTotal(100)
.setMaxConnPerRoute(20)
.setConnectionTimeToLive(60, TimeUnit.SECONDS)
.build();
}
5. 内存分析工具
启用监控
# JVM监控参数
-XX:+PrintGC
-XX:+PrintGCDetails
-XX:+PrintGCTimeStamps
-Dcom.sun.management.jmxremote
-Dcom.sun.management.jmxremote.port=9999
内存分析脚本
#!/bin/bash
# 监控Java进程内存使用
PID=$(jps | grep YourApp | awk '{print $1}')
jstat -gc $PID 1000 5
jmap -heap $PID
jcmd $PID VM.native_memory summary
6. 实例部署策略
Docker容器配置
FROM openjdk:11-jre-slim
COPY app.jar /app.jar
ENTRYPOINT ["java", "-Xms1g", "-Xmx1g", "-XX:+UseG1GC", "-jar", "/app.jar"]
# docker-compose.yml
version: '3'
services:
app1:
image: your-app
mem_limit: 1.5g
mem_reservation: 1g
app2:
image: your-app
mem_limit: 1.5g
mem_reservation: 1g
7. 性能调优建议
代码层面优化
// 避免内存泄漏
@Service
public class MemoryOptimizedService {
// 使用弱引用避免内存泄漏
private final Map<String, WeakReference<ExpensiveObject>> cache =
new ConcurrentHashMap<>();
// 及时关闭资源
public void processFile(String filePath) {
try (BufferedReader reader = Files.newBufferedReader(Paths.get(filePath))) {
// 处理文件
} catch (IOException e) {
log.error("Error processing file", e);
}
}
}
批处理优化
// 分批处理大数据
public void processLargeData(List<Data> dataList) {
int batchSize = 1000;
for (int i = 0; i < dataList.size(); i += batchSize) {
int end = Math.min(i + batchSize, dataList.size());
List<Data> batch = dataList.subList(i, end);
// 处理批次
processBatch(batch);
// 显式释放
batch.clear();
}
}
8. 监控和告警
Prometheus配置
# prometheus.yml
scrape_configs:
- job_name: 'java-apps'
metrics_path: '/actuator/prometheus'
static_configs:
- targets: ['app1:8080', 'app2:8080']
关键监控指标
- 堆内存使用率
- GC频率和暂停时间
- 线程数
- 连接池使用情况
- 缓存命中率
通过以上优化措施,可以在4GB内存中稳定运行2-3个Java实例,具体数量取决于应用的实际负载和性能要求。建议持续监控和调优,找到最佳平衡点。
CLOUD技术笔记