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