在 1核1G 内存的服务器 上运行 Java 应用(如 Spring Boot)和 MySQL,资源非常有限,因此必须进行精细化调优,否则很容易出现内存溢出(OOM)、响应缓慢、服务崩溃等问题。
以下是针对 Java + MySQL 在 1核1G 服务器上的调优建议:
✅ 一、MySQL 调优(重点:内存占用)
MySQL 是内存大户,尤其默认配置可能占用 500MB+,必须精简。
1. 修改 MySQL 配置文件(通常是 my.cnf 或 my.ini)
[mysqld]
# 基础设置
port = 3306
bind-address = 127.0.0.1
skip-name-resolve
# 禁用 DNS 解析,加快连接
# 关键:降低内存使用
key_buffer_size = 16M
max_allowed_packet = 1M
table_open_cache = 32
sort_buffer_size = 64K
read_buffer_size = 64K
read_rnd_buffer_size = 256K
join_buffer_size = 128K
tmp_table_size = 32M
max_heap_table_size = 32M
# InnoDB 设置(重点)
innodb_buffer_pool_size = 128M # 通常占物理内存的 50%~70%,1G 机建议 128M~256M
innodb_log_file_size = 32M # 日志文件大小,可设小点
innodb_log_buffer_size = 1M # 日志缓冲区
innodb_flush_log_at_trx_commit = 2 # 提高性能,牺牲一点持久性(可接受)
innodb_file_per_table = ON
innodb_flush_method = O_DIRECT
# 连接相关
max_connections = 50 # 默认151,太高会耗内存,50足够小应用
thread_cache_size = 4
query_cache_type = 0 # 禁用查询缓存(MySQL 8.0 已移除)
query_cache_size = 0 # 节省内存
# 超时设置
wait_timeout = 60
interactive_timeout = 60
✅ 说明:
innodb_buffer_pool_size是最大内存占用项,建议 128M~256M,不要超过 300M。- 禁用 query cache(在小内存下反而拖慢性能)。
- 减少连接数,避免连接过多耗尽内存。
2. 其他优化建议
- 使用 MySQL 8.0 的轻量模式 或考虑 MariaDB(更轻量)。
- 定期清理无用数据、索引。
- 避免大查询、全表扫描,加必要索引。
- 使用
slow_query_log分析慢查询。
✅ 二、Java 应用调优(JVM + 应用层)
1. JVM 参数调优(关键!)
假设你运行的是 Spring Boot 应用,JVM 堆内存不能太大,否则容易 OOM。
java -Xms128m -Xmx256m
-XX:MetaspaceSize=64m -XX:MaxMetaspaceSize=96m
-XX:+UseG1GC
-XX:MaxGCPauseMillis=200
-XX:+HeapDumpOnOutOfMemoryError
-XX:HeapDumpPath=/tmp/heapdump.hprof
-jar your-app.jar
参数解释:
| 参数 | 说明 |
|---|---|
-Xms128m |
初始堆内存 128MB |
-Xmx256m |
最大堆内存 256MB(不能更大) |
-XX:MetaspaceSize=64m |
元空间初始大小 |
-XX:MaxMetaspaceSize=96m |
防止元空间无限增长 |
-XX:+UseG1GC |
使用 G1 垃圾回收器(适合小堆) |
-XX:MaxGCPauseMillis=200 |
控制 GC 暂停时间 |
-XX:+HeapDumpOnOutOfMemoryError |
OOM 时生成 dump,便于排查 |
⚠️ 注意:JVM 进程本身 + 堆外内存 + 线程栈等,总共可能占用 400~500MB,因此堆不能设太大。
2. 应用层优化
- 减少启动加载的 Bean:避免 @ComponentScan 扫描过多包。
- 关闭无用的自动配置:Spring Boot 可通过
spring.autoconfigure.exclude关闭。 - 使用轻量数据库连接池,如 HikariCP(默认),并控制连接数:
# application.yml
spring:
datasource:
hikari:
maximum-pool-size: 8 # 1核1G,建议 5~10
minimum-idle: 2
connection-timeout: 30000
idle-timeout: 600000
max-lifetime: 1800000
- 避免内存泄漏:如缓存不用
ConcurrentHashMap自己管理,应使用Caffeine并设置大小限制。 - 日志级别设为
INFO或WARN,避免DEBUG输出大量日志。 - 静态资源尽量交给 Nginx 托管,Java 只处理动态请求。
✅ 三、系统级优化
1. 使用 Swap(虚拟内存)
1G 内存容易爆,建议加 1G Swap:
# 创建 1G swap 文件
sudo fallocate -l 1G /swapfile
sudo chmod 600 /swapfile
sudo mkswap /swapfile
sudo swapon /swapfile
# 永久生效
echo '/swapfile none swap sw 0 0' >> /etc/fstab
⚠️ Swap 会降低性能,但能防止 OOM Kill。
2. 监控资源使用
# 实时查看
top
htop
free -h
mysqladmin -u root -p processlist
3. 使用轻量 Web 服务器(如 Nginx)
将静态资源交给 Nginx,Java 只作为后端 API。
server {
listen 80;
location / {
proxy_pass http://localhost:8080;
}
}
✅ 四、综合建议
| 项目 | 推荐值 |
|---|---|
| MySQL 内存占用 | ≤ 300MB |
| Java 堆内存 | 128~256MB |
| 最大连接数(MySQL) | 50 |
| 数据库连接池大小 | 5~8 |
| 是否启用 Swap | 是(1G) |
| 是否使用缓存 | 谨慎,限制大小 |
| 是否跑多个服务 | 不建议,只跑必要服务 |
✅ 五、可选替代方案(更省资源)
- 使用 SQLite 替代 MySQL(读写并发低时)。
- 使用 Spring Boot + Undertow 替代 Tomcat(更轻量)。
- 使用 GraalVM Native Image 编译为原生镜像(启动快、内存小,但构建复杂)。
总结
在 1核1G 服务器上运行 Java + MySQL 是勉强可行的,但必须:
- 严格限制 MySQL 内存(尤其是
innodb_buffer_pool_size)。 - 控制 JVM 堆大小(≤256M)。
- 减少并发连接和线程数。
- 开启 Swap 防止 OOM。
- 持续监控内存和 CPU 使用。
💡 适合:低流量后台、个人项目、学习环境。
❌ 不适合:高并发、生产级应用。
如需更高性能,建议升级到 2核2G 或使用云函数(Serverless)拆分服务。
如有具体应用类型(如博客、API 服务等),可进一步优化配置。欢迎补充!
CLOUD技术博