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