SpringBoot项目占用内存优化

一、JVM内存配置优化

1. 合理设置堆内存

bash 复制代码
#!/bin/bash
JAVA_OPTS="-Xms256m -Xmx512m \
-XX:MetaspaceSize=128m \
-XX:MaxMetaspaceSize=256m \
-XX:+UseG1GC \
-XX:MaxGCPauseMillis=200 \
-XX:ParallelGCThreads=4 \
-XX:ConcGCThreads=2 \
-XX:+DisableExplicitGC \
-XX:+HeapDumpOnOutOfMemoryError \
-XX:HeapDumpPath=/tmp/heapdump.hprof"
java $JAVA_OPTS -jar your-application.jar

2. 垃圾回收器选择

复制代码

propertiesCopy Code

# 年轻代使用G1GC(适合多核服务器) -XX:+UseG1GC -XX:MaxGCPauseMillis=200 -XX:InitiatingHeapOccupancyPercent=45

二、Spring框架级优化

bash 复制代码
# 关闭不需要的自动配置
spring.autoconfigure.exclude=org.springframework.boot.autoconfigure.jmx.JmxAutoConfiguration

# 数据源连接池配置
spring.datasource.hikari.maximum-pool-size=5
spring.datasource.hikari.minimum-idle=2

# 缓存配置
spring.cache.type=simple
spring.cache.caffeine.spec=maximumSize=100,expireAfterWrite=60s

# 会话管理
server.servlet.session.timeout=30m
server.servlet.session.persistent=false

# 关闭JMX 
# 当设置为 true 时,Spring Boot 会向 JMX 服务器(如 JConsole、VisualVM)暴露应用的管理端点(如Bean信息、指标监控等)。
# 允许通过 JMX 工具远程监控和管理应用运行时状态
# 禁用后仅影响JMX监控,不影响Actuator的HTTP端点(如/actuator/health)。
spring.jmx.enabled=false
# 禁用指标收集
management.metrics.enabled=false
# 延迟初始化
spring.main.lazy-initialization=true
java 复制代码
@Configuration
@Lazy
public class LazyConfig {
    
    @Bean
    @Lazy
    @Scope(proxyMode = ScopedProxyMode.TARGET_CLASS)
    public HeavyService heavyService() {
        return new HeavyService();
    }
    
    @Bean
    public FilterRegistrationBean<MyFilter> myFilter() {
        FilterRegistrationBean<MyFilter> registration = new FilterRegistrationBean<>();
        registration.setFilter(new MyFilter());
        registration.setEnabled(false); // 默认禁用
        return registration;
    }
}

1. 组件懒加载

javaCopy Code

@Configuration @Lazy public class MyConfig { @Bean @Lazy public HeavyService heavyService() { return new HeavyService(); } }

2. 减少自动扫描范围

复制代码

javaCopy Code

@SpringBootApplication(scanBasePackages = "com.your.core.package") public class Application { public static void main(String[] args) { SpringApplication.run(Application.class, args); } }

三、依赖库优化

1. 排除不必要的依赖

XML 复制代码
<project>
    <dependencies>
        <!-- 使用Undertow替代Tomcat -->
        <dependency>
            <groupId>org.springframework.boot</groupId>
            <artifactId>spring-boot-starter-web</artifactId>
            <exclusions>
                <exclusion>
                    <groupId>org.springframework.boot</groupId>
                    <artifactId>spring-boot-starter-tomcat</artifactId>
                </exclusion>
            </exclusions>
        </dependency>
        <dependency>
            <groupId>org.springframework.boot</groupId>
            <artifactId>spring-boot-starter-undertow</artifactId>
        </dependency>
        
        <!-- 排除不需要的日志实现 -->
        <dependency>
            <groupId>org.springframework.boot</groupId>
            <artifactId>spring-boot-starter</artifactId>
            <exclusions>
                <exclusion>
                    <groupId>org.springframework.boot</groupId>
                    <artifactId>spring-boot-starter-logging</artifactId>
                </exclusion>
            </exclusions>
        </dependency>
        <dependency>
            <groupId>org.springframework.boot</groupId>
            <artifactId>spring-boot-starter-log4j2</artifactId>
        </dependency>
    </dependencies>
    
    <build>
        <plugins>
            <plugin>
                <groupId>org.springframework.boot</groupId>
                <artifactId>spring-boot-maven-plugin</artifactId>
                <configuration>
                    <excludes>
                        <exclude>
                            <groupId>org.projectlombok</groupId>
                            <artifactId>lombok</artifactId>
                        </exclude>
                    </excludes>
                </configuration>
            </plugin>
        </plugins>
    </build>
</project>

<dependency> <groupId>org.springframework.boot</groupId> <artifactId>spring-boot-starter-web</artifactId> <exclusions> <exclusion> <groupId>org.springframework.boot</groupId> <artifactId>spring-boot-starter-logging</artifactId> </exclusion> </exclusions> </dependency>

2. 使用轻量级替代方案

复制代码

xmlCopy Code

<!-- 用Undertow代替Tomcat --> <dependency> <groupId>org.springframework.boot</groupId> <artifactId>spring-boot-starter-web</artifactId> <exclusions> <exclusion> <groupId>org.springframework.boot</groupId> <artifactId>spring-boot-starter-tomcat</artifactId> </exclusion> </exclusions> </dependency> <dependency> <groupId>org.springframework.boot</groupId> <artifactId>spring-boot-starter-undertow</artifactId> </dependency>

四、运行时优化

1. 缓存控制

复制代码

javaCopy Code

@Configuration @EnableCaching public class CacheConfig { @Bean public CacheManager cacheManager() { return new ConcurrentMapCacheManager("myCache"); } }

2. 会话管理

复制代码

propertiesCopy Code

# 使用内存友好的会话存储 spring.session.store-type=none # 或使用Redis时的优化配置 spring.session.redis.flush-mode=on_save spring.session.redis.save-mode=on_set_attribute

五、监控与分析工具

java 复制代码
@Component
public class MemoryMonitor {
    
    @Scheduled(fixedRate = 60000)
    public void logMemoryUsage() {
        Runtime runtime = Runtime.getRuntime();
        long usedMB = (runtime.totalMemory() - runtime.freeMemory()) / 1024 / 1024;
        long maxMB = runtime.maxMemory() / 1024 / 1024;
        System.out.printf("Memory usage: %dMB/%dMB (%.1f%%)\n", 
            usedMB, maxMB, (usedMB * 100.0 / maxMB));
    }
    
    @PreDestroy
    public void cleanup() {
        // 释放资源
    }
}

1. 内存分析工具

复制代码

bashCopy Code

# 生成堆转储文件 jmap -dump:live,format=b,file=heap.hprof <pid> # 使用VisualVM或Eclipse MAT分析

2. Spring Boot Actuator配置

复制代码

propertiesCopy Code

management.endpoints.web.exposure.include=health,info,metrics management.endpoint.metrics.enabled=true management.metrics.export.prometheus.enabled=true

六、生产环境建议

1. 容器化优化

复制代码

dockerfileCopy Code

FROM adoptopenjdk:11-jre-hotspot as builder WORKDIR application COPY target/*.jar application.jar RUN java -Djarmode=layertools -jar application.jar extract FROM adoptopenjdk:11-jre-hotspot COPY --from=builder application/dependencies/ ./ COPY --from=builder application/spring-boot-loader/ ./ COPY --from=builder application/application/ ./ ENTRYPOINT ["java", "-Xms256m", "-Xmx256m", "org.springframework.boot.loader.JarLauncher"]

2. 类数据共享(CDS)

复制代码

bashCopy Code

# 生成共享归档文件 java -Xshare:dump -XX:SharedArchiveFile=app-cds.jsa -jar your-app.jar # 使用共享归档启动 java -Xshare:on -XX:SharedArchiveFile=app-cds.jsa -jar your-app.jar

通过以上优化措施,典型Spring Boot应用的内存占用可以从1GB+降低到300-500MB,极端情况下甚至可以达到200MB以下。建议定期使用内存分析工具监控应用内存使用情况,持续优化。

相关推荐
程序猿DD17 分钟前
OctaFuse Gateway 2.15.0:MCP 聚合、向量 Embeddings 与官方目录同步
后端·agent
蛋蛋的就会顺顺的3 小时前
hot100 p0——栈,贪心算法,动态规划
java·前端·javascript·算法·leetcode·力扣
余槐i3 小时前
PostgreSQL 函数索引报错 must be immutable:3种绕法与代价
数据库·后端·sql·postgresql·性能优化
需要8263 小时前
Spring Bean 生命周期:从实例化到销毁的完整钩子
java·后端·spring
小 黄 鸡3 小时前
HashMap 面试必会知识点详解(JDK 8)
java·面试·职场和发展
凤山老林4 小时前
Spring Boot 接入国密 SM2/SM3/SM4 的一些实践记录
spring boot·后端·python
伯恩bourne5 小时前
Spring Boot Bean 注册的两种方式:@Component 家族 vs @Configuration + @Bean
java·spring boot·后端
张彦峰ZYF5 小时前
停顿短不等于延迟低:G1、ZGC 与低延迟服务的目标分野、代价账本与选型标定
后端·回收暂停、应用停止总时长·到达安全点、分配停滞·屏障吃吞吐、并发线程吃核心·并发窗口吃堆余量·分区式靠挑回收集兑现目标·染色指针式不支持压缩引用
silvamux_5 小时前
curl 测试 OpenAI 兼容 API 的完整流程
java·人工智能·缓存·ai·oneapi
pride.li6 小时前
第03章 Python 教程-基础语法:注释与变量
服务器·前端·后端·python·算法·计算机视觉