2核2G(2C2G)跑Java,属于典型的“小马拉大车”。JVM默认配置通常是为多核、大内存设计的,直接启动大概率会触发OOM(内存溢出)或者GC频繁导致CPU飙高。
要在这么小的资源里让Spring Boot或普通Java应用跑稳,核心思路就三个:限制堆内存、减少线程开销、优化垃圾回收。
以下是具体要改的参数和配置逻辑:
1. JVM 堆内存参数(最核心)
不要依赖JVM自动计算堆大小,必须手动指定。
-Xms(初始堆) 和-Xmx(最大堆)- 建议值:
-Xms512m -Xmx512m或-Xms1g -Xmx1g。 - 逻辑:服务器总内存2G,OS和后台进程至少预留500M-800M。留给Java的堆内存不能超过1.5G,否则系统直接卡死。对于大多数轻量级Spring Boot应用,512M~1G足够。保持初始值和最大值一致,避免运行时动态扩容带来的性能抖动。
- 建议值:
-XX:MetaspaceSize和-XX:MaxMetaspaceSize- 建议值:
-XX:MetaspaceSize=128m -XX:MaxMetaspaceSize=256m。 - 逻辑:元空间存放类信息。如果不限制,在某些场景下可能无限增长耗尽内存。设个上限兜底。
- 建议值:
2. 线程池与栈大小
2核CPU并发能力有限,不要开太多线程。
-Xss(线程栈大小)- 建议值:
-Xss256k或-Xss512k。 - 逻辑:默认通常是1M。在2G内存机器上,如果每个线程占1M,开几十个线程就没了。改为256k或512k可以容纳更多线程,但要注意过深的递归调用可能导致StackOverflowError。一般Web应用深度不够深,这个值很安全。
- 建议值:
- Tomcat/Jetty 连接器线程数
- 如果你用内置Tomcat,修改
application.yml或server.xml:server: tomcat: threads: max: 50 # 默认200太夸张了 min-spare: 10 - 逻辑:2核CPU处理不了几百个并发连接。50-100个线程足够应对常规流量。
- 如果你用内置Tomcat,修改
3. 垃圾回收器选择
这是提升稳定性的关键。
- 推荐方案 A:G1 GC(JDK 8u24+ / JDK 11+)
- 参数:
-XX:+UseG1GC - 附加调优:
-XX:MaxGCPauseMillis=200 - 理由:G1对堆大小敏感,适合中等堆内存。能控制停顿时间,避免Full GC导致的长时间STW(Stop The World)。
- 参数:
- 推荐方案 B:Parallel GC(JDK 8 默认)
- 如果不换JDK版本,就用默认的Parallel GC,但需关注Young GC频率。
- 避坑指南:
- 不要用 CMS(已废弃/移除)。
- 不要用 ZGC/Shenandoah(它们需要更大的堆和更复杂的内存管理,在小内存下优势不明显甚至 overhead 更高)。
4. 操作系统层面优化(Linux)
除了Java参数,Linux内核参数也要配合,防止文件句柄耗尽或连接超时。
- 文件描述符限制
- 执行
ulimit -n 65535 - 或在
/etc/security/limits.conf中添加:* soft nofile 65535 * hard nofile 65535 - 理由:高并发时TCP连接数多,默认1024很容易打满。
- 执行
- Swap 分区
- 强烈建议开启 Swap,哪怕只有1G。
- 理由:2G物理内存极易被吃光。如果没有Swap,一旦内存略超,进程直接被Kill(OOM Killer)。有了Swap,虽然会变慢(磁盘IO),但至少不会崩。设置Swappiness为10-30,避免过度使用Swap。
- 防火墙与安全组
- 阿里云控制台记得开对应端口,别只改了Linux iptables/firewalld忘了云安全组。
5. 应用层瘦身建议
参数调优有极限,代码和架构也得减负:
- 去掉不必要的依赖:比如不需要Spring Security就别引入,不需要Thymeleaf就别打包前端模板引擎。
- 禁用Debug日志:生产环境务必设为
INFO或WARN,DEBUG级别日志量巨大,会疯狂写磁盘并消耗CPU。 - 关闭Actuator监控端点:如果不需要健康检查接口暴露给公网,关掉
/actuator/env等敏感端点,减少内存占用和安全风险。 - 使用轻量级框架:如果能选,优先考虑 Quarkus 或 Micronaut,它们启动快、内存占用极低。如果必须用Spring Boot,考虑 Spring Boot 3 + GraalVM Native Image(编译成原生镜像,内存占用可降至100M以内,但构建复杂度高,看团队技术储备)。
总结配置示例(JDK 8+)
java -server
-Xms512m -Xmx512m
-XX:MetaspaceSize=128m -XX:MaxMetaspaceSize=256m
-Xss256k
-XX:+UseG1GC
-XX:MaxGCPauseMillis=200
-jar app.jar
最后提醒:2C2G真的不适合高并发场景。如果是个人项目、内部工具、低流量博客,完全够用。如果是面向公众的商业应用,建议至少升级到 2C4G 或 4C8G,内存成本增加不多,但稳定性和体验提升巨大。
云计算HECS