在仅有 2G 内存的主机上搭建 Java 网站,运行 Tomcat + MySQL + Java 应用,资源非常紧张。为了避免 OOM(Out of Memory),必须对 Tomcat 和 MySQL 进行精细化调优,合理分配内存资源。
以下是具体的优化建议:
🔧 一、总体内存规划(2G = 2048MB)
| 组件 | 建议内存分配 | 说明 |
|---|---|---|
| JVM (Tomcat) | 512MB ~ 768MB | 避免过大导致系统崩溃 |
| MySQL | 512MB ~ 768MB | 根据使用场景调整 |
| 操作系统 & 其他进程 | ≥ 512MB | 留给系统缓存、SSH、日志等 |
⚠️ 总和不要超过 1.5GB,留出缓冲空间防止 swap 频繁或 OOM Killer 干预。
🐱 二、Tomcat 调优(JVM 参数)
1. 设置合理的 JVM 内存参数
编辑 bin/catalina.sh(Linux)或 catalina.bat(Windows),添加:
export JAVA_OPTS="-Xms256m -Xmx512m -XX:MetaspaceSize=64m -XX:MaxMetaspaceSize=128m -XX:+UseG1GC -XX:MaxGCPauseMillis=200"
参数解释:
-Xms256m:JVM 初始堆大小,避免频繁扩容。-Xmx512m:最大堆内存,防止占用过多。-XX:MetaspaceSize=64m -XX:MaxMetaspaceSize=128m:控制元空间(替代永久代),防止类加载过多导致 OOM。-XX:+UseG1GC:使用 G1 垃圾回收器,适合小堆且低延迟。-XX:MaxGCPauseMillis=200:目标最大 GC 暂停时间。
✅ 如果应用简单(如单体 Spring Boot 小项目),512MB 堆足够。
2. 减少 Tomcat 自身负载
- 关闭不必要的 Webapp(如 docs, examples, manager):
删除$CATALINA_HOME/webapps/下无用目录。 - 使用轻量级 Connector(NIO):
在server.xml中确保使用 NIO:
<Connector port="8080" protocol="HTTP/1.1"
connectionTimeout="20000"
redirectPort="8443"
executor="tomcatThreadPool"
protocol="org.apache.coyote.http11.Http11NioProtocol" />
- 控制线程数(避免线程爆炸):
<Executor name="tomcatThreadPool" namePrefix="http-nio-8080-exec-"
maxThreads="100" minSpareThreads="10" maxIdleTime="60000"/>
🐬 三、MySQL 调优(重点!默认配置太耗内存)
MySQL 默认配置可能占用 >1GB,必须精简。
编辑 /etc/mysql/my.cnf 或 /etc/my.cnf:
[mysqld]
# 基础设置
datadir=/var/lib/mysql
socket=/var/lib/mysql/mysql.sock
# 关键内存参数(总内存控制在 512~768MB)
innodb_buffer_pool_size = 256M # 最大可设 384M,但 256M 更安全
key_buffer_size = 32M # MyISAM 索引缓存(若不用 MyISAM 可更小)
query_cache_type = 0 # 禁用查询缓存(MySQL 8+ 已移除,5.7 可关)
query_cache_size = 0 # 节省内存
tmp_table_size = 32M
max_heap_table_size = 32M
sort_buffer_size = 512K
read_buffer_size = 512K
read_rnd_buffer_size = 512K
join_buffer_size = 512K
thread_stack = 192K
table_open_cache = 64
table_definition_cache = 400
# 连接相关
max_connections = 50 # 避免连接过多耗内存
thread_cache_size = 4
wait_timeout = 60
interactive_timeout = 60
# 日志(可选关闭以省资源)
# slow_query_log = 0
# log_error_verbosity = 1
# InnoDB 专用
innodb_log_file_size = 48M
innodb_log_buffer_size = 8M
innodb_flush_log_at_trx_commit = 2 # 提升性能,轻微降低持久性
innodb_flush_method = O_DIRECT
innodb_file_per_table = ON
# 字符集
character-set-server = utf8mb4
collation-server = utf8mb4_unicode_ci
✅ 以上配置下,MySQL 内存占用约 300~500MB,适合 2G 主机。
🛠 四、系统级优化
1. 添加 Swap(虚拟内存)
2G 内存建议添加 1~2G Swap,防止 OOM 直接崩溃。
# 创建 2GB swap 文件
sudo fallocate -l 2G /swapfile
sudo chmod 600 /swapfile
sudo mkswap /swapfile
sudo swapon /swapfile
# 永久生效(写入 /etc/fstab)
echo '/swapfile none swap sw 0 0' | sudo tee -a /etc/fstab
⚠️ Swap 不是万能,只是防止 OOM Killer 强杀进程。
2. 监控内存使用
使用命令监控:
free -h
top
htop # 更直观
jstat -gc <pid> # 查看 JVM GC 情况
3. 限制后台服务
关闭不需要的服务(如 Apache、Redis、邮件服务等),只保留必要组件。
📈 五、应用层优化(Java 代码层面)
- 避免内存泄漏:检查静态集合、未关闭流、监听器等。
- 分页查询大数据:禁止
SELECT * FROM large_table。 - 使用连接池并限制最大连接数(如 HikariCP):
# Spring Boot 示例
spring:
datasource:
hikari:
maximum-pool-size: 10
minimum-idle: 2
connection-timeout: 30000
- 启用缓存(如 Caffeine)减少数据库压力。
✅ 总结:关键点清单
| 项目 | 推荐值 |
|---|---|
| JVM 堆内存 | -Xms256m -Xmx512m |
| Metaspace | 64m ~ 128m |
| GC 算法 | G1GC |
| MySQL buffer pool | 256M |
| MySQL max_connections | 50 |
| Swap 空间 | 2GB |
| Tomcat 线程数 | maxThreads=100 |
| 禁用 MySQL 查询缓存 | query_cache_size=0 |
| 监控工具 | htop, jstat, free |
✅ 最终目标:
让 Tomcat + MySQL + OS 总内存占用控制在 1.5GB 以内,留出 500MB 缓冲,避免频繁 swap 或 OOM。
如有条件,建议升级到 4G 内存,体验会大幅提升。但在 2G 环境下,以上调优足以支撑小型 Java 网站稳定运行。
PHPWP博客