在 4GB 内存的服务器(CentOS 或 Ubuntu)上运行 Spring Boot + MySQL,需精细调优以避免 OOM、频繁 GC 或 MySQL 崩溃。以下是生产可用的最低但稳健配置建议(非开发/演示环境),兼顾稳定性与基本并发能力(如 50–100 并发请求):
✅ 总体原则
- 内存严格分配:4GB = 4096MB → 预留 512MB 给 OS + 系统进程(必须!)
- 剩余 ~3.5GB 合理分配给 JVM(Spring Boot)和 MySQL
- 禁用 swap(或设 swappiness=1):避免 JVM GC 时因 swap 导致卡死
- 使用 OpenJDK 17+(LTS):G1 GC 更适合小内存场景
🛠️ 1. Java / Spring Boot 配置(推荐 JAR 方式部署)
| 项目 | 推荐值 | 说明 |
|---|---|---|
| JVM 堆内存 | -Xms1280m -Xmx1280m(1.25GB) |
✅ 固定堆大小,避免动态伸缩开销;留足空间给 Metaspace、Direct Memory、线程栈等 |
| GC 参数 | -XX:+UseG1GC -XX:MaxGCPauseMillis=200 -XX:+UseStringDeduplication |
G1 在小堆下更可控;避免 CMS(已废弃)或 Parallel GC(停顿长) |
| Metaspace | -XX:MetaspaceSize=256m -XX:MaxMetaspaceSize=384m |
防止动态扩容导致 Full GC |
| 线程栈 | -Xss256k |
默认 1MB 太大,4GB 下易耗尽内存(尤其高并发时) |
| 其他 | -Dfile.encoding=UTF-8 -Duser.timezone=Asia/Shanghai |
必备基础项 |
✅ 启动示例(application.jar):
java -Xms1280m -Xmx1280m -XX:MetaspaceSize=256m -XX:MaxMetaspaceSize=384m -Xss256k -XX:+UseG1GC -XX:MaxGCPauseMillis=200 -XX:+UseStringDeduplication -jar application.jar --spring.profiles.active=prod
✅ Spring Boot 应用层优化(application-prod.yml):
server:
port: 8080
tomcat:
max-connections: 200 # 连接数上限(非并发线程数)
accept-count: 100 # 队列长度(防突发)
threads:
min: 10
max: 50 # Tomcat 工作线程池(关键!避免默认200吃光内存)
spring:
datasource:
hikari:
maximum-pool-size: 15 # ⚠️ MySQL 连接池上限(见下文 MySQL 配置)
minimum-idle: 5
connection-timeout: 30000
idle-timeout: 600000
max-lifetime: 1800000
# 关闭非必要功能(减内存占用)
management:
endpoints:
web:
exposure:
include: "health,info,metrics,prometheus" # 按需开启
endpoint:
health:
show-details: never
🐬 2. MySQL 配置(MySQL 8.0+,推荐 Percona Server 或 MariaDB 10.11+ 更省资源)
| 参数 | 推荐值 | 说明 |
|---|---|---|
innodb_buffer_pool_size |
1024M(1GB) | ✅ 最关键!InnoDB 缓存,占总内存 25%~30%,过高会导致系统 OOM |
max_connections |
100 |
与 Hikari maximum-pool-size 匹配(建议 ≤15~20,避免连接堆积) |
innodb_log_file_size |
128M |
日志文件大小(需初始化后首次修改并重建日志) |
key_buffer_size |
16M |
MyISAM(若不用可设为 0) |
query_cache_type |
0 |
❌ 必须关闭(MySQL 8.0+ 已移除,5.7 中也建议关) |
tmp_table_size / max_heap_table_size |
32M |
防止大查询内存溢出 |
sort_buffer_size |
512K |
每连接排序缓冲(勿设过大) |
read_buffer_size |
256K |
同上 |
table_open_cache |
400 |
表缓存(避免频繁打开文件) |
✅ my.cnf 示例(/etc/my.cnf):
[mysqld] bind-address = 127.0.0.1 skip-networking = OFF # 如需远程访问,否则保持 ON(更安全) innodb_buffer_pool_size = 1024M max_connections = 100 innodb_log_file_size = 128M key_buffer_size = 16M tmp_table_size = 32M max_heap_table_size = 32M sort_buffer_size = 512K read_buffer_size = 256K table_open_cache = 400 thread_cache_size = 8 wait_timeout = 300 interactive_timeout = 300 # 安全加固(必加) sql_mode = STRICT_TRANS_TABLES,NO_ZERO_DATE,NO_ZERO_IN_DATE,ERROR_FOR_DIVISION_BY_ZERO🔁 生效方式:修改后重启 MySQL,并确认
SHOW VARIABLES LIKE 'innodb_buffer_pool_size';
📊 内存分配汇总(4GB 总内存)
| 组件 | 占用 | 说明 |
|---|---|---|
| Linux OS + 系统进程 | ≥512MB | 必须预留(sshd、cron、journald、内核等) |
| Spring Boot JVM 堆 | 1280MB | 含 Young/Old 区(G1 分区) |
| JVM 非堆(Metaspace + CodeCache + Direct Mem + 线程栈) | ≈300–400MB | 按 50 线程估算(50 × 256KB ≈ 12.5MB) |
| MySQL InnoDB Buffer Pool | 1024MB | 主要内存消耗者 |
| MySQL 其他缓存/连接内存 | ≈200MB | sort_buffer, tmp_table, 连接结构体等 |
| 总计估算 | ≈3.5–3.7GB | ✅ 安全余量(200–500MB) |
⚠️ 关键注意事项(避坑指南)
- 绝不使用
mysqlroot 远程直连应用 → 创建专用用户 + 限制 host + 最小权限 - 禁用 MySQL 的
performance_schema(若无需监控):
performance_schema = OFF(节省 ~100MB 内存) - Spring Boot 禁用 DevTools、Actuator 全量端点、Thymeleaf 模板缓存(若用)
- 定期清理日志:
journalctl --vacuum-size=100M- Spring Boot
logging.file.max-size=10MB
- 监控必备:
htop/free -h/jstat -gc <pid>- MySQL:
SHOW PROCESSLIST;,SHOW ENGINE INNODB STATUSG
- 备份策略:用
mysqldump --single-transaction(避免锁表),每日压缩备份到异地
✅ 替代轻量方案(如仍卡顿)
| 场景 | 推荐方案 |
|---|---|
| 极低流量(<10 QPS)、纯 API | 改用 H2 Database(内存模式) + spring.h2.console.enabled=true(仅开发)→ 不适用于生产 |
| 需要持久化但极简 | SQLite(通过 sqlite-jdbc + 自定义 DataSource)→ 无服务进程,省内存,但不支持并发写 |
| MySQL 实在扛不住 | MariaDB 10.11 + aria engine(比 InnoDB 更省内存)或启用 innodb_buffer_pool_instances=1 |
✅ 最终验证清单
- [ ]
free -h显示可用内存 ≥ 300MB 闲置 - [ ]
jstat -gc <pid>显示 GC 频率 < 1次/分钟,Full GC = 0 - [ ]
mysqladmin status显示Threads_connected≤ 20 - [ ]
curl http://localhost:8080/actuator/health返回UP - [ ] 压测(如
ab -n 1000 -c 50 http://localhost:8080/api/test)无 5xx/OOM
如需进一步优化(如 Nginx 反向X_X、HTTPS 卸载、连接池监控),欢迎补充你的具体场景(QPS预期、数据量、是否含文件上传/定时任务等),我可为你定制调优方案。
需要我提供 一键部署脚本(Ubuntu/22.04 + MySQL 8.0 + JDK 17 + Spring Boot 启动模板) 吗?
云计算HECS