如何將開發環境的 Spring Boot 應用程序內存降低 40% 以上
本文翻譯自:https://medium.com/@satanjim/how-we-reduced-the-memory-consumption-of-spring-boot-application-over-40-for-the-development-c8a5813fac23
在開發基礎的 Spring Boot 應用程序時,我們需要考慮可承受的內存消耗。隨著添加更多依賴項,內存消耗也會增加。對于整體應用程序,通常仍然可以承受內存消耗,但當我們開發多個微服務并在本地計算機上運行時,這可能成為一場噩夢,影響開發效率。
Spring Boot 和 JVM 都帶有一些默認配置,適用于大多數情況,甚至在某些生產環境中也能勝任。但是如果我們能調整一些配置來適應本地開發,就可以顯著減少內存消耗。請注意,我不是 JVM 和 Spring Boot 方面的專家,只是想在這篇文章中分享一些我自己的經驗。
誰消耗了內存
首先,讓我們了解一下,到底是誰在消耗內存呢?沒錯,是 JVM。但是它是如何做到的呢?
要深入了解這個問題,我們需要了解 JVM 的內部結構,但這超出了本文的范圍。簡單來說,JVM 的內存消耗可以分成堆(Heap)、元空間(Metaspace)、每個線程的堆棧(Thread Stack)以及其他。
內存消耗
為了減少內存消耗,我們需要向 JVM 顯式地傳遞一些參數。
首先,我們需要進行一些前置準備:
- 安裝 Docker 和 docker-compose
- 使用 Java 17 版本(但是 8 到最新版本之間的任何版本應該都可以,除了 Java 8 中的一些舊補丁)
- 使用 Spring Boot
接下來,我們可以配置一些參數。創建一個名為"dev.jvm.conf"的文件,并輸入以下值(稍后我們會解釋這些值的含義):
# dev.jvm.conf
# 覆蓋應用程序的屬性
SERVER_TOMCAT_ACCEPT_COUNT=3
SERVER_TOMCAT_MAX_CONNECTIONS=3
SERVER_TOMCAT_THREADS_MAX=3
SERVER_TOMCAT_THREADS_MIN_SPARE=1
SPRING_MAIN_LAZY_INITIALIZATION=true
# 設置JVM參數
JAVA_TOOL_OPTIONS=-XX:+UseSerialGC -Xss512k -XX:MaxRAM=200m
然后,我們使用 docker-compose 將這些環境變量傳遞到容器中:
# docker-compose.yml
services:
service1:
image: service1:dev
env_file:
- dev.jvm.conf
service2:
image: service2:dev
env_file:
- dev.jvm.conf
現在運行docker-compose up命令,您應該能看到一些差異。
接下來,讓我們詳細討論一下這些配置
在開始之前,請記住,降低某些值不會直接減少本地環境中的內存使用量,因為本地環境中通常不會有那么多請求。我們添加閾值的目的是,即使在本地環境中,如果我們開始收到更多請求,也要限制其數量。這最終將有助于限制內存使用。
- SERVER_TOMCAT_ACCEPT_COUNT:該屬性設置了當所有可能的請求處理線程都在使用時,傳入連接請求的最大隊列長度。當服務器負載較重且所有工作線程都繁忙時,傳入的請求將被放入隊列中。如果隊列已滿,額外的連接請求將被拒絕。默認值為 100。
- SERVER_TOMCAT_MAX_CONNECTIONS:該屬性定義了 Tomcat 服務器同時能夠處理的最大連接數。默認值為 8192。
- SERVER_TOMCAT_THREADS_MAX:該屬性控制 Tomcat 服務器將創建的請求處理線程的最大數量。默認值為 200。
- SERVER_TOMCAT_THREADS_MIN_SPARE:該屬性為嵌入式 Tomcat 服務器設置了最小備用線程數。默認值為 10。
- SPRING_MAIN_LAZY_INITIALIZATION:將該屬性值設置為 true 意味著應用程序中的所有 bean 都將延遲初始化。這將有助于縮短啟動時間。
- JAVA_TOOL_OPTIONS:使用該屬性,我們可以向 JVM 傳遞一些額外的參數。讓我們來談談其中的每個參數意義。
- -XX:+UseSerialGC:這個參數會使 JVM 使用單線程進行內聯垃圾收集,而不是使用專用的 GC 線程。
- -Xss512k:這個參數將每個線程的堆棧大小限制為 512KB,而不是默認的 1MB。
- -XX:MaxRAM=200m:這個參數設置 JVM 最大可使用的 RAM 內存為 200MB。
這是一些簡單的調整,但它們可以在本地開發環境中顯著減少內存消耗。當然,根據您的具體情況,您可能需要進一步進行調整。這只是一個起點,您可以根據實際需求進行優化。
總結
總而言之,通過適當配置 JVM 和 Spring Boot,并理解內存消耗的原理,我們可以降低本地開發環境的內存消耗,提高工作效率。希望這些提示能對您有所幫助!