Spring Boot项目在Tomcat内嵌容器下通常占用多少系统资源?

Spring Boot 项目在使用内嵌 Tomcat(默认)时的系统资源占用没有固定值,但可以给出典型范围和关键影响因素,帮助你合理评估和优化:


✅ 一、典型资源占用范围(空/最小化应用,JDK 17+,Spring Boot 3.x)

资源类型 典型范围(启动后稳定态) 说明
JVM 堆内存 (Heap) 64–256 MB java -jar app.jar 默认未设 -Xmx 时,HotSpot JVM 通常按物理内存比例分配(如 1/4),但最小约 64MB;简单 REST API 应用常驻堆约 80–120MB。
总内存占用(RSS) 120–350 MB 包含堆 + 元空间(Metaspace)+ 线程栈 + 直接内存 + Tomcat 原生结构等。实测 Spring Boot 3.2 + Web Starter + Actuator 的“Hello World”应用约 180–220 MB(Linux ps aux --sort=-%mem)。
CPU 占用 < 1%(空闲时) 无请求时几乎不消耗 CPU;Tomcat 启动线程池(默认 200 线程)处于等待状态,仅少量定时任务(如 Session 清理、Actuator 指标收集)。
线程数 25–40 个 内嵌 Tomcat 默认:1 个主线程 + 1 个 Catalina shutdown 线程 + NIO selector 线程(通常 2–4)+ HTTP worker 线程池(默认 maxThreads=200,但实际创建数取决于负载;空闲时仅保留 corePoolSize=10 左右活跃线程 + 几个守护线程)。

🔍 示例验证(Linux/macOS):

# 启动最简应用(spring-boot-starter-web + 一个 @RestController)
java -jar demo.jar &

# 查看 RSS 内存(单位 KB)
ps -o pid,rss,comm -p $(pgrep -f "demo.jar")  
# 输出示例:12345  215680  java   → ≈ 215 MB

# 查看线程数
ls /proc/$(pgrep -f "demo.jar")/task | wc -l
# 输出示例:32

⚙️ 二、影响资源占用的关键因素

因素 影响说明 优化建议
依赖数量 每多一个 starter(如 spring-boot-starter-data-jpa, spring-boot-starter-security)会增加类加载、Bean 创建、自动配置开销,显著提升元空间(Metaspace)和堆内存。 使用 spring-boot-dependencies 分析依赖树(mvn dependency:tree),移除未用 starter;启用 @ConditionalOnClass 精简自动配置。
Web 容器配置 Tomcat 默认 maxThreads=200,但线程栈(默认 1MB/线程)会占用大量虚拟内存(VIRT),虽不计入 RSS,但影响容器环境(如 Docker 内存限制)。 调整 server.tomcat.threads.max=50;减小栈大小 -Xss256k(需测试稳定性)。
JVM 参数 未显式设置 -Xms/-Xmx 会导致堆动态伸缩,GC 频繁;默认 Metaspace 无上限可能 OOM。 生产推荐:-Xms256m -Xmx256m -XX:MetaspaceSize=128m -XX:MaxMetaspaceSize=256m
应用功能复杂度 数据库连接池(HikariCP 默认 10 连接)、缓存(Caffeine/Ehcache)、定时任务、WebSocket、Actuator 端点等都会增加内存与线程。 关闭不用的 Actuator 端点(management.endpoints.web.exposure.include=health,info);调小连接池 spring.datasource.hikari.maximum-pool-size=5
JDK 版本 JDK 17+ 的 ZGC/Shenandoah 或更优的 GC 算法可降低 GC 开销;JDK 21+ 虚拟线程(Project Loom)可大幅减少线程内存占用(需 Tomcat 10.1.15+ 支持)。 生产环境优先选用 JDK 17 LTS 或 JDK 21 LTS,搭配合适 GC(如 -XX:+UseZGC)。

📊 三、对比参考(实测数据,Linux x64, JDK 17)

场景 RSS 内存 线程数 说明
最小 Web 应用(仅 spring-boot-starter-web + 1 controller) ~180 MB ~28 无数据库、无安全、无 Actuator
+ HikariCP(5 连接) + JPA ~260 MB ~35 加载 Hibernate、JDBC 驱动、连接池对象
+ Spring Security ~320 MB ~42 Security Filter Chain、AuthenticationManager 等
+ Actuator 全开启 ~340 MB ~45 Metrics、Health、Env 等端点内存开销

💡 提示:使用 Spring Boot DevTools 时,开发阶段内存会额外增加 50–100MB(热重载机制),生产务必排除 devtools


✅ 四、最佳实践建议

  1. 始终显式设置 JVM 参数(尤其生产):

    java -Xms256m -Xmx256m -XX:MetaspaceSize=128m -XX:MaxMetaspaceSize=256m 
        -XX:+UseZGC -Dfile.encoding=UTF-8 
        -jar myapp.jar
  2. 精简依赖:用 spring-boot-starter-webflux 替代 web(响应式栈更轻量,但适用场景不同);或考虑 GraalVM Native Image(冷启动快、内存≈40–80MB,但构建复杂、反射需配置)。

  3. 监控基线:启动后用 jstat -gc <pid> 观察 GC;用 jcmd <pid> VM.native_memory summary 查看本地内存分布。

  4. 容器化注意:Docker 中设置 --memory=512m 并配合 JVM 参数,避免因容器内存限制触发 OOM Killer(JVM 无法感知 cgroup 限制,需 JDK 8u191+/10+ 支持 -XX:+UseContainerSupport)。


如需进一步优化,可提供你的 pom.xmlbuild.gradle 片段 + 应用功能描述,我可以帮你分析具体瓶颈并给出定制化调优方案。

未经允许不得转载:ECLOUD博客 » Spring Boot项目在Tomcat内嵌容器下通常占用多少系统资源?