Optimizējiet savu Java lietojumprogrammu veiktspēju un resursu izmantošanu, izmantojot šo visaptverošo ceļvedi par Java virtuālās mašīnas (JVM) atkritumu savākšanas regulēšanu. Uzziniet par dažādiem atkritumu savācējiem, regulēšanas parametriem un praktiskiem piemēriem globālajām lietojumprogrammām.
Java virtuālā mašīna: dziļa iedziļināšanās atkritumu savākšanas regulēšanā
Java spēks slēpjas tās platformas neatkarībā, ko panāk ar Java virtuālo mašīnu (JVM). Būtisks JVM aspekts ir tās automātiskā atmiņas pārvaldība, ko galvenokārt nodrošina atkritumu savācējs (GC). GC izpratne un regulēšana ir ļoti svarīga optimālai lietojumprogrammas veiktspējai, īpaši globālajām lietojumprogrammām, kas nodarbojas ar daudzveidīgām darba slodzēm un lieliem datu apjomiem. Šis ceļvedis sniedz visaptverošu GC regulēšanas pārskatu, kas ietver dažādus atkritumu savācējus, regulēšanas parametrus un praktiskus piemērus, lai palīdzētu optimizēt jūsu Java lietojumprogrammas.
Atkritumu savākšanas izpratne programmā Java
Atkritumu savākšana ir process, kas automātiski atgūst atmiņu, ko aizņem objekti, kurus programma vairs neizmanto. Tas novērš atmiņas noplūdes un vienkāršo izstrādi, atbrīvojot izstrādātājus no manuālās atmiņas pārvaldības, kas ir ievērojama priekšrocība, salīdzinot ar tādām valodām kā C un C++. JVM GC identificē un noņem šos neizmantotos objektus, padarot atmiņu pieejamu turpmākai objektu izveidei. Atkritumu savācēja izvēle un tā regulēšanas parametri būtiski ietekmē lietojumprogrammu veiktspēju, tostarp:
- Lietojumprogrammu pauzes: GC pauzes, kas pazīstamas arī kā 'stop-the-world' notikumi, kad lietojumprogrammas pavedieni tiek apturēti, kamēr darbojas GC. Biežas vai garas pauzes var būtiski ietekmēt lietotāja pieredzi.
- Caurlaidspēja: ātrums, ar kādu lietojumprogramma var apstrādāt uzdevumus. GC var patērēt daļu no CPU resursiem, kurus varētu izmantot faktiskajam lietojumprogrammu darbam, tādējādi ietekmējot caurlaidspēju.
- Atmiņas izmantošana: cik efektīvi lietojumprogramma izmanto pieejamo atmiņu. Nepareizi konfigurēts GC var izraisīt pārmērīgu atmiņas izmantošanu un pat kļūdas "nav atmiņas".
- Latence: laiks, kas nepieciešams lietojumprogrammai, lai atbildētu uz pieprasījumu. GC pauzes tieši veicina latentumu.
Dažādi atkritumu savācēji JVM
JVM piedāvā dažādus atkritumu savācējus, katram no kuriem ir savas stiprās un vājās puses. Atkritumu savācēja izvēle ir atkarīga no lietojumprogrammas prasībām un darba slodzes raksturojuma. Apskatīsim dažus no tiem:
1. Sērijas atkritumu savācējs
Sērijas GC ir vienpavediena savācējs, kas galvenokārt ir piemērots lietojumprogrammām, kas darbojas vienkodolu mašīnās vai tām, kurām ir ļoti mazas kaudzes. Tas ir vienkāršākais savācējs un veic pilnus GC ciklus. Tā galvenais trūkums ir garas 'stop-the-world' pauzes, kas padara to nepiemērotu ražošanas vidēm, kurām nepieciešama zema latentums.
2. Paralēlais atkritumu savācējs (caurlaidspējas savācējs)
Paralēlais GC, kas pazīstams arī kā caurlaidspējas savācējs, mērķis ir maksimāli palielināt lietojumprogrammas caurlaidspēju. Tas izmanto vairākus pavedienus, lai veiktu mazas un lielas atkritumu savākšanas operācijas, samazinot atsevišķu GC ciklu ilgumu. Tā ir laba izvēle lietojumprogrammām, kur caurlaidspējas maksimizēšana ir svarīgāka par zemu latentumu, piemēram, pakešu apstrādes darbiem.
3. CMS (Concurrent Mark Sweep) atkritumu savācējs (novecojis)
CMS tika izstrādāts, lai samazinātu pauzes laikus, vienlaikus veicot lielāko daļu atkritumu savākšanas ar lietojumprogrammu pavedieniem. Tā izmantoja vienlaicīgu atzīmēšanas un slaucīšanas pieeju. Lai gan CMS nodrošināja mazākas pauzes nekā paralēlais GC, tas varēja ciest no fragmentācijas un tam bija lielāks CPU režijas. CMS ir novecojis kopš Java 9 un vairs nav ieteicams jaunām lietojumprogrammām. To ir aizstājis G1GC.
4. G1GC (Garbage-First Garbage Collector)
G1GC ir noklusējuma atkritumu savācējs kopš Java 9, un tas ir paredzēts gan lieliem kaudzes izmēriem, gan zemas pauzes laikam. Tas sadala kaudzi reģionos un prioritāti piešķir reģionu vākšanai, kas ir visvairāk piepildīti ar atkritumiem, tāpēc arī nosaukums 'Garbage-First'. G1GC nodrošina labu līdzsvaru starp caurlaidspēju un latentumu, padarot to par daudzpusīgu izvēli plašam lietojumprogrammu klāstam. Tā mērķis ir saglabāt pauzes laikus zem noteikta mērķa (piemēram, 200 milisekundēm).
5. ZGC (Z atkritumu savācējs)
ZGC ir zemas latentuma atkritumu savācējs, kas ieviests programmā Java 11 (eksperimentāls programmā Java 11, gatavs ražošanai no Java 15). Tā mērķis ir samazināt GC pauzes laiku līdz pat 10 milisekundēm neatkarīgi no kaudzes lieluma. ZGC darbojas vienlaicīgi, lietojumprogrammai darbojoties gandrīz nepārtraukti. Tas ir piemērots lietojumprogrammām, kurām nepieciešama ārkārtīgi zema latentums, piemēram, augstfrekvences tirdzniecības sistēmām vai tiešsaistes spēļu platformām. ZGC izmanto krāsainus rādītājus, lai izsekotu objektu atsauces.
6. Shenandoah atkritumu savācējs
Shenandoah ir zemas pauzes laika atkritumu savācējs, ko izstrādājis Red Hat un ir potenciāla alternatīva ZGC. Tāpat tas cenšas nodrošināt ļoti īsus pauzes laikus, veicot vienlaicīgu atkritumu savākšanu. Shenandoah galvenā atšķirība ir tā, ka tas var saspiest kaudzi vienlaicīgi, kas var palīdzēt samazināt fragmentāciju. Shenandoah ir gatavs ražošanai OpenJDK un Red Hat Java izplatījumos. Tas ir pazīstams ar zemo pauzes laiku un caurlaidspējas īpašībām. Shenandoah ir pilnībā vienlaicīgs ar lietojumprogrammu, kurai ir priekšrocība, ka tā jebkurā brīdī neaptur lietojumprogrammas izpildi. Darbs tiek veikts, izmantojot papildu pavedienu.
Galvenie GC regulēšanas parametri
Atkritumu savākšanas regulēšana ietver dažādu parametru pielāgošanu, lai optimizētu veiktspēju. Šeit ir daži svarīgi parametri, kas jāapsver, klasificēti skaidrībai:
1. Kaudzes izmēra konfigurācija
-Xms
(Minimālais kaudzes izmērs): iestata sākotnējo kaudzes lielumu. Parasti ir laba prakse iestatīt to uz to pašu vērtību kā-Xmx
, lai novērstu JVM kaudzes lieluma maiņu izpildes laikā.-Xmx
(Maksimālais kaudzes izmērs): iestata maksimālo kaudzes lielumu. Šis ir vissvarīgākais konfigurējamais parametrs. Pareizās vērtības atrašana ietver eksperimentēšanu un uzraudzību. Lielāka kaudze var uzlabot caurlaidspēju, bet var palielināt pauzes laiku, ja GC ir jāstrādā smagāk.-Xmn
(Jaunās paaudzes izmērs): norāda jaunās paaudzes lielumu. Jaunā paaudze ir vieta, kur sākotnēji tiek piešķirti jauni objekti. Lielāka jaunā paaudze var samazināt mazo GC biežumu. G1GC gadījumā jaunās paaudzes lielums tiek pārvaldīts automātiski, bet to var pielāgot, izmantojot parametrus-XX:G1NewSizePercent
un-XX:G1MaxNewSizePercent
.
2. Atkritumu savācēja atlase
-XX:+UseSerialGC
: iespējo sērijas GC.-XX:+UseParallelGC
: iespējo paralēlo GC (caurlaidspējas savācējs).-XX:+UseG1GC
: iespējo G1GC. Šis ir noklusējums Java 9 un jaunākām versijām.-XX:+UseZGC
: iespējo ZGC.-XX:+UseShenandoahGC
: iespējo Shenandoah GC.
3. G1GC-specifiski parametri
-XX:MaxGCPauseMillis=
: iestata mērķa maksimālo pauzes laiku milisekundēs G1GC. GC mēģinās sasniegt šo mērķi, bet tas nav garantēts.-XX:G1HeapRegionSize=
: iestata reģionu lielumu kaudzē G1GC. Reģiona lieluma palielināšana var potenciāli samazināt GC režijas izmaksas.-XX:G1NewSizePercent=
: iestata minimālo kaudzes procentuālo daļu, ko izmanto jaunajai paaudzei G1GC.-XX:G1MaxNewSizePercent=
: iestata maksimālo kaudzes procentuālo daļu, ko izmanto jaunajai paaudzei G1GC.-XX:G1ReservePercent=
: Atmiņas apjoms, kas rezervēts jaunu objektu piešķiršanai. Noklusējuma vērtība ir 10%.-XX:G1MixedGCCountTarget=
: norāda jaukto atkritumu savākšanas operāciju mērķa skaitu ciklā.
4. ZGC-specifiski parametri
-XX:ZUncommitDelay=
: Laiks sekundēs, cik ilgi ZGC gaidīs, pirms atmiņas neatgriešanas operētājsistēmā.-XX:ZAllocationSpikeFactor=
: piešķiršanas ātruma pīķa faktors. Lielāka vērtība nozīmē, ka GC ir atļauts strādāt agresīvāk, lai savāktu atkritumus, un var patērēt vairāk CPU ciklu.
5. Citi svarīgi parametri
-XX:+PrintGCDetails
: iespējo detalizētu GC reģistrēšanu, sniedzot vērtīgu informāciju par GC cikliem, pauzes laikiem un atmiņas izmantošanu. Tas ir ļoti svarīgi GC darbības analīzei.-XX:+PrintGCTimeStamps
: iekļauj laika zīmogus GC žurnāla izvadē.-XX:+UseStringDeduplication
(Java 8u20 un jaunākām versijām, G1GC): samazina atmiņas izmantošanu, deduplicējot identiskas virknes kaudzē.-XX:+ExplicitGCInvokesConcurrentAndUnloadsClasses
: iespējo vai atspējo skaidru GC izsaukumu izmantošanu pašreizējā JDK. Tas ir noderīgi, lai novērstu veiktspējas pasliktināšanos ražošanas vidē.-XX:+HeapDumpOnOutOfMemoryError
: ģenerē kaudzes izgāztuvi, kad rodas OutOfMemoryError, kas ļauj detalizēti analizēt atmiņas izmantošanu un identificēt atmiņas noplūdes.-XX:HeapDumpPath=
: norāda atrašanās vietu, kur jāraksta kaudzes izgāztuves fails.
Praktiski GC regulēšanas piemēri
Apskatīsim dažus praktiskus piemērus dažādiem scenārijiem. Atcerieties, ka tie ir sākumpunkti, un tiem ir nepieciešama eksperimentēšana un uzraudzība, pamatojoties uz jūsu lietojumprogrammas īpašībām. Ir svarīgi uzraudzīt lietojumprogrammas, lai būtu piemērota bāzes līnija. Rezultāti var atšķirties atkarībā no aparatūras.
1. Pakešu apstrādes lietojumprogramma (vērsta uz caurlaidspēju)
Pakešu apstrādes lietojumprogrammām galvenais mērķis parasti ir maksimāli palielināt caurlaidspēju. Zems latentums nav tik kritisks. Paralēlais GC bieži vien ir labs risinājums.
java -Xms4g -Xmx4g -XX:+UseParallelGC -XX:+PrintGCDetails -XX:+PrintGCTimeStamps -jar mybatchapp.jar
Šajā piemērā mēs iestatām minimālo un maksimālo kaudzes izmēru uz 4 GB, iespējojot paralēlo GC un iespējojot detalizētu GC reģistrēšanu.
2. Tīmekļa lietojumprogramma (jutīga pret latentumu)
Tīmekļa lietojumprogrammām zems latentums ir ļoti svarīgs labai lietotāja pieredzei. G1GC vai ZGC (vai Shenandoah) bieži tiek doti priekšroka.
Izmantojot G1GC:
java -Xms8g -Xmx8g -XX:+UseG1GC -XX:MaxGCPauseMillis=200 -XX:+PrintGCDetails -XX:+PrintGCTimeStamps -jar mywebapp.jar
Šī konfigurācija iestata minimālo un maksimālo kaudzes lielumu uz 8 GB, iespējo G1GC un iestata mērķa maksimālo pauzes laiku uz 200 milisekundēm. Pielāgojiet MaxGCPauseMillis
vērtību, pamatojoties uz jūsu veiktspējas prasībām.
Izmantojot ZGC (nepieciešama Java 11+):
java -Xms8g -Xmx8g -XX:+UseZGC -XX:+PrintGCDetails -XX:+PrintGCTimeStamps -jar mywebapp.jar
Šis piemērs iespējo ZGC ar līdzīgu kaudzes konfigurāciju. Tā kā ZGC ir paredzēts ļoti zemam latentumam, parasti nav nepieciešams konfigurēt pauzes laika mērķi. Jūs varētu pievienot parametrus noteiktiem scenārijiem; piemēram, ja jums ir problēmas ar piešķiršanas ātrumu, varat izmēģināt -XX:ZAllocationSpikeFactor=2
3. Augstfrekvences tirdzniecības sistēma (ārkārtīgi zems latentums)
Augstfrekvences tirdzniecības sistēmām ārkārtīgi zems latentums ir vissvarīgākais. ZGC ir ideāls risinājums, ja pieņem, ka lietojumprogramma ir ar to saderīga. Ja izmantojat Java 8 vai jums ir saderības problēmas, apsveriet Shenandoah.
java -Xms16g -Xmx16g -XX:+UseZGC -XX:+PrintGCDetails -XX:+PrintGCTimeStamps -jar mytradingapp.jar
Līdzīgi tīmekļa lietojumprogrammas piemēram, mēs iestatām kaudzes lielumu un iespējojam ZGC. Apsveriet iespēju vēl vairāk noregulēt ZGC specifiskos parametrus, pamatojoties uz darba slodzi.
4. Lietojumprogrammas ar lieliem datu kopumiem
Lietojumprogrammām, kas nodarbojas ar ļoti lieliem datu kopumiem, ir nepieciešams rūpīgi apsvērt. Iespējams, būs jāizmanto lielāks kaudzes lielums, un uzraudzība kļūst vēl svarīgāka. Datus var arī kešot jaunajā paaudzē, ja datu kopa ir maza un lielums ir tuvu jaunajai paaudzei.
Apsveriet šādus punktus:
- Objektu piešķiršanas ātrums: Ja jūsu lietojumprogramma izveido lielu skaitu īslaicīgu objektu, jaunā paaudze varētu būt pietiekama.
- Objekta dzīves ilgums: Ja objekti mēdz dzīvot ilgāk, jums būs jāuzrauga paaugstināšanas ātrums no jaunās paaudzes uz veco paaudzi.
- Atmiņas nospiedums: Ja lietojumprogramma ir atkarīga no atmiņas un ja rodas OutOfMemoryError izņēmumi, objekta lieluma samazināšana vai tā īslaicīga padarīšana varētu atrisināt problēmu.
Lielai datu kopai ir svarīgs jaunās paaudzes un vecās paaudzes attiecība. Apsveriet šo piemēru, lai sasniegtu zemas pauzes laikus:
java -Xms32g -Xmx32g -XX:+UseG1GC -XX:MaxGCPauseMillis=100 -XX:G1NewSizePercent=20 -XX:G1MaxNewSizePercent=30 -XX:+PrintGCDetails -XX:+PrintGCTimeStamps -jar mydatasetapp.jar
Šis piemērs iestata lielāku kaudzi (32 GB) un precīzi noregulē G1GC ar zemāku mērķa pauzes laiku un pielāgotu jaunās paaudzes lielumu. Atbilstoši pielāgojiet parametrus.
Uzraudzība un analīze
GC regulēšana nav vienreizējs pasākums; tas ir iteratīvs process, kas prasa rūpīgu uzraudzību un analīzi. Lūk, kā piekļūt uzraudzībai:
1. GC reģistrēšana
Iespējojiet detalizētu GC reģistrēšanu, izmantojot tādus parametrus kā -XX:+PrintGCDetails
, -XX:+PrintGCTimeStamps
un -Xloggc:
. Analizējiet žurnālfailus, lai saprastu GC darbību, tostarp pauzes laikus, GC ciklu biežumu un atmiņas izmantošanas modeļus. Apsveriet iespēju izmantot tādus rīkus kā GCViewer vai GCeasy, lai vizualizētu un analizētu GC žurnālus.
2. Lietojumprogrammu veiktspējas uzraudzības (APM) rīki
Izmantojiet APM rīkus (piemēram, Datadog, New Relic, AppDynamics), lai uzraudzītu lietojumprogrammu veiktspēju, ieskaitot CPU izmantošanu, atmiņas izmantošanu, atbildes laikus un kļūdu rādītājus. Šie rīki var palīdzēt identificēt GC saistītos šaurumus un sniegt ieskatu lietojumprogrammu darbībā. Tirgū esošos rīkus, piemēram, Prometheus un Grafana, var izmantot arī, lai redzētu reāllaika veiktspējas ieskatu.
3. Kaudzes izgāztuves
Veiciet kaudzes izgāztuves (izmantojot -XX:+HeapDumpOnOutOfMemoryError
un -XX:HeapDumpPath=
), kad rodas OutOfMemoryErrors. Analizējiet kaudzes izgāztuves, izmantojot tādus rīkus kā Eclipse MAT (atmiņas analizatora rīks), lai identificētu atmiņas noplūdes un saprastu objektu piešķiršanas modeļus. Kaudzes izgāztuves sniedz lietojumprogrammas atmiņas izmantošanas momentuzņēmumu noteiktā laika punktā.
4. Profilēšana
Izmantojiet Java profilēšanas rīkus (piemēram, JProfiler, YourKit), lai identificētu veiktspējas šaurumus savā kodā. Šie rīki var sniegt ieskatu objektu izveidē, metožu izsaukumos un CPU izmantošanā, kas var netieši palīdzēt noregulēt GC, optimizējot lietojumprogrammas kodu.
GC regulēšanas paraugprakses
- Sāciet ar noklusējumiem: JVM noklusējumi bieži vien ir labs sākumpunkts. Nepārregulējiet priekšlaicīgi.
- Izprotiet savu lietojumprogrammu: zināt savas lietojumprogrammas darba slodzi, objektu piešķiršanas modeļus un atmiņas izmantošanas īpašības.
- Pārbaudiet vidēs, kas ir līdzīgas ražošanai: pārbaudiet GC konfigurācijas vidēs, kas cieši atgādina jūsu ražošanas vidi, lai precīzi novērtētu veiktspējas ietekmi.
- Nepārtraukti uzraugiet: nepārtraukti uzraugiet GC darbību un lietojumprogrammas veiktspēju. Pielāgojiet regulēšanas parametrus pēc nepieciešamības, pamatojoties uz novērotajiem rezultātiem.
- Izolējiet mainīgos: regulējot, mainiet tikai vienu parametru vienlaikus, lai saprastu katras izmaiņas ietekmi.
- Izvairieties no priekšlaicīgas optimizācijas: neoptimizējiet paredzamai problēmai bez ticamiem datiem un analīzes.
- Apsveriet koda optimizāciju: optimizējiet savu kodu, lai samazinātu objektu izveidi un atkritumu savākšanas režiju. Piemēram, atkārtoti izmantojiet objektus, kad vien iespējams.
- Sekojiet līdzi: esiet informēti par jaunākajiem sasniegumiem GC tehnoloģijā un JVM atjauninājumiem. Jaunās JVM versijas bieži ietver atkritumu savākšanas uzlabojumus.
- Dokumentējiet savu regulēšanu: dokumentējiet GC konfigurāciju, jūsu izvēles pamatojumu un veiktspējas rezultātus. Tas palīdzēs turpmākajā apkopē un problēmu novēršanā.
Secinājums
Atkritumu savākšanas regulēšana ir būtisks Java lietojumprogrammas veiktspējas optimizācijas aspekts. Izprotot dažādus atkritumu savācējus, regulēšanas parametrus un uzraudzības metodes, jūs varat efektīvi optimizēt savas lietojumprogrammas, lai izpildītu īpašas veiktspējas prasības. Atcerieties, ka GC regulēšana ir iteratīvs process un prasa nepārtrauktu uzraudzību un analīzi, lai sasniegtu optimālus rezultātus. Sāciet ar noklusējumiem, izprotiet savu lietojumprogrammu un eksperimentējiet ar dažādām konfigurācijām, lai atrastu labāko risinājumu savām vajadzībām. Ar pareizu konfigurāciju un uzraudzību jūs varat nodrošināt, ka jūsu Java lietojumprogrammas darbojas efektīvi un uzticami neatkarīgi no jūsu globālā sasniedzamības.