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以下。建议定期使用内存分析工具监控应用内存使用情况,持续优化。

相关推荐
无处不在的海贼19 分钟前
小明的Java面试奇遇之发票系统相关深度实战挑战
java·经验分享·面试
武子康23 分钟前
Java-109 深入浅出 MySQL MHA主从故障切换机制详解 高可用终极方案
java·数据库·后端·mysql·性能优化·架构·系统架构
秋难降43 分钟前
代码界的 “建筑师”:建造者模式,让复杂对象构建井然有序
java·后端·设计模式
孤雪心殇1 小时前
如何安全,高效,优雅的提升linux的glibc版本
linux·后端·golang·glibc
BillKu1 小时前
Spring Boot 多环境配置
java·spring boot·后端
new_daimond1 小时前
Spring Boot项目集成日志系统使用完整指南
spring boot·后端
哈基米喜欢哈哈哈2 小时前
Kafka复制机制
笔记·分布式·后端·kafka
一叶飘零_sweeeet3 小时前
如何避免MyBatis二级缓存中的脏读
java·redis·mybatis
Trust yourself2433 小时前
IDEA控制台乱码(Tomcat)解决方法
java·tomcat·intellij-idea