在仅有 2GB 内存的服务器上同时运行 Tomcat 和 MySQL,资源非常紧张。为了确保系统稳定运行并避免内存溢出(OOM),必须对两个服务进行精细的内存优化。以下是详细的优化建议:
一、总体策略
-
合理分配内存:建议分配:
- Tomcat:512MB ~ 768MB
- MySQL:512MB ~ 768MB
- 系统和其他进程:预留 512MB 左右
-
关闭不必要的服务:如 Apache、Postfix、cron 中非关键任务等。
-
使用轻量级操作系统:如 Ubuntu Server LTS 最小安装或 Alpine Linux。
-
启用 Swap(虚拟内存):至少设置 1GB 的 swap 分区,防止 OOM 崩溃。
二、Tomcat 内存优化
1. 设置 JVM 堆内存
编辑 catalina.sh 或 setenv.sh 文件,设置合理的堆大小:
export JAVA_OPTS="-Xms256m -Xmx512m -XX:MetaspaceSize=64m -XX:MaxMetaspaceSize=128m -XX:+UseG1GC"
-Xms256m:初始堆大小-Xmx512m:最大堆大小(根据应用调整,不建议超过 768m)-XX:MetaspaceSize:元空间大小,替代永久代-XX:+UseG1GC:使用 G1 垃圾回收器,适合中等堆大小
⚠️ 避免设置过大堆内存,否则易导致频繁 Full GC 或系统卡顿。
2. 减少线程数
修改 server.xml 中的 Connector 配置:
<Connector port="8080" protocol="HTTP/1.1"
maxThreads="100"
minSpareThreads="10"
maxSpareThreads="50"
connectionTimeout="20000"
acceptCount="100"
disableUploadTimeout="true" />
maxThreads="100":默认是 200,降低以节省内存acceptCount="100":等待队列长度
3. 关闭不必要的功能
- 删除示例应用(
webapps/examples,manager,host-manager) - 禁用 JMX 监控(除非必要)
三、MySQL 内存优化(以 MySQL 5.7+/8.0 为例)
编辑 /etc/mysql/my.cnf 或 /etc/my.cnf,配置如下:
[mysqld]
# 基础设置
datadir=/var/lib/mysql
socket=/var/lib/mysql/mysql.sock
# 内存相关(重点)
key_buffer_size = 32M
max_allowed_packet = 16M
thread_stack = 192K
thread_cache_size = 4
sort_buffer_size = 256K
read_buffer_size = 256K
read_rnd_buffer_size = 256K
join_buffer_size = 256K
tmp_table_size = 32M
max_heap_table_size = 32M
# InnoDB 设置(最关键)
innodb_buffer_pool_size = 256M # 核心缓存,占总内存 1/4~1/3
innodb_log_file_size = 64M
innodb_log_buffer_size = 8M
innodb_flush_log_at_trx_commit = 2
innodb_file_per_table = 1
innodb_flush_method = O_DIRECT
# 连接相关
max_connections = 50 # 默认 151,太高会耗内存
table_open_cache = 256
table_definition_cache = 256
# 其他
query_cache_type = 0 # 关闭查询缓存(MySQL 8.0 已移除)
query_cache_size = 0
performance_schema = OFF # 可关闭以省内存
说明:
innodb_buffer_pool_size = 256M:这是 MySQL 最重要的内存参数,不宜超过 512M。max_connections = 50:每个连接消耗内存,减少并发连接数。- 关闭
performance_schema和query_cache节省内存。 - 使用
O_DIRECT避免双重缓存。
✅ 修改
innodb_log_file_size后需先停止 MySQL,删除旧日志文件再重启。
四、系统级优化
1. 添加 Swap(强烈建议)
# 创建 1GB swap 文件
sudo fallocate -l 1G /swapfile
sudo chmod 600 /swapfile
sudo mkswap /swapfile
sudo swapon /swapfile
# 永久生效
echo '/swapfile none swap sw 0 0' | sudo tee -a /etc/fstab
2. 调整 Swappiness
# 减少 swap 使用倾向(0~100,默认 60)
echo 'vm.swappiness=10' | sudo tee -a /etc/sysctl.conf
sudo sysctl -p
3. 监控内存使用
free -h # 查看内存和 swap
htop # 实时监控进程
journalctl -u mysql --since "1 hour ago" # 查看服务日志
tail -f /var/log/tomcat/catalina.out # 查看 Tomcat 日志
五、其他建议
- 使用 Nginx 代替 Apache:更轻量,可做反向X_X和静态资源处理。
- 定期清理日志:Tomcat 和 MySQL 日志可能迅速膨胀。
- 应用层面优化:
- 避免内存泄漏(检查代码中的静态集合、未关闭的连接等)
- 使用连接池(如 HikariCP),合理设置最大连接数
- 考虑分离服务:长期来看,建议将 Tomcat 和 MySQL 部署在不同服务器。
六、验证配置是否生效
- Tomcat:启动后执行
ps aux | grep java,查看 JVM 参数。 - MySQL:登录后执行:
SHOW VARIABLES LIKE 'innodb_buffer_pool_size'; SHOW VARIABLES LIKE 'max_connections';
总结
| 项目 | 推荐值 |
|---|---|
| 总内存 | 2GB |
| Tomcat 堆内存 | -Xmx512m |
| MySQL 缓冲池 | innodb_buffer_pool_size=256M |
| 最大连接数 | 50 |
| Swap | 1GB |
| 系统保留 | ≥512MB |
通过以上优化,可以在 2GB 内存服务器上稳定运行中小型 Java Web 应用 + MySQL 数据库。但应持续监控性能,在访问量上升时及时扩容或拆分服务。
CLOUD云计算