Fórumok
Van egy szerverem. Java 11-re nemrég tértünk át, és az egyik szerver megbokrosodott.
Eddig beérte max. 5-6G memóriával, most hirtelenjében annyit eszik amennyit csak tud.
Ha készítek belőle memory dumpot, pl. egy 23G-ás RES memória foglalásról, akkor a profiler azt mondja, hogy az élő objektumok mérete 1G alatti. Mi a fene lehet a másik 22G?
Ötletek?
UPDATE:
A heap memórián az élő objektumok 900 mega körül vannak. Ezen kívül van még 22 (most már ~30) giga valami még.
Azaz mivel lehetne kideríteni, hogy mi az ami a heap-on kívül eszi a memóriát?
Hozzászólások
nem értek a JVM-hez de linux szintjén milyen memóriáról van szó? file cache, anon page?
Linux szinten használt memóriáról van szó azaz resource memória, azaz a topban pl. itt látod: RES.
hotspot vagy j9? a jvm-váltáson túl a kódhoz is hozzányúltatok? a dependenciák változtak?
hprof-ot készítettünk jmap-el, a dependenciákhoz is nyúltunk, a kódot is igazgatni kellett, valamint a WildFly-t is frissítettük alatta. OpenJDK 11
Akkor ki kell elemezni a változásokat.
Köszönöm, de ez elég hosszadalmas lenne. Hiszen át kellene nézni a WildFly változásokat, a dependency változásokat (melyik lehet hibás?), kódban is rengeteg volt, meg még a Java-nak is lehet gondja.
Nem a heap ami önmagában eszik, hanem valami a heapen kívül növekszik. Ha azt lehetne valahogy megállapítani, hogy mi a heap-en kívül a tartalma a memóriának, az sokat segíthetne.
Értem. Tapasztalataim szerint nincs magic ilyen esetben. Csak a szisztematikus keresés.
Mekkora heap-et adtál amúgy a JVM-nek? Ha azon bőven túlterjeszkedik, akkor a JVM a probléma általában (és/vagy Unsafe interfészen át való off-heap memóriafoglalás), azt hiába nézed Java profiler-el, nem fogod látni a hibát.
Próbálj ezzel indítani: `-XX:NativeMemoryTracking=[summary | detail]`
https://iotguru.cloud
Köszönöm. Ezt kipróbáltam.
-Xmx16g van adva. Ennél jóval túllóg. Most olyan 32g a RES.
Úgy látom a class metadata környékén van gond:
Bár még nem értem miért.
Ez 1,7 GB, nem ez lesz. Be tudod másolni a summary eredményét? Nincs abban semmi szenzitív.
https://iotguru.cloud
Ez most egy teszt szerver. Nem az éles. Ezen igyekszem valahogy kitalálni, hogy melyik alkalmazás okozza.
Itt még csak 5.1G a foglalás a RES-ből.
Ebből egyelőre semmi komoly nem látszik. Próbálj mondjuk óránként kinyerni egy ilyen dump-ot az élesből és nézd meg, hogy melyik része növekszik abnormálisan trendszerűen.
https://iotguru.cloud
Az élest csak holnap tudom intézni.
Most sikerült meghajtanom a teszt szervert és felment 5.5 gigára a mem használat.
Az újabb summary:
Próbálkozz a teszt szerveren a
beállítással.
Melegítsd be a dolgokat, majd kérj egy állapotot.
Hajtsd meg a rendszered, hogy nőjön a memória.
Majd kérj diff-et.
Native Memory Tracking
DIFF:
De ebből még mindig nem derült ki számomra, hogy hol keressem az okot.
A class terület nőtt meg, a heap nem mozdult. Szinte mindenki nőtt valamennyit.
Kicsit növögetnek, az üzemszerű, főleg az első néhány órában. Akkor lesz érdekes, amikor már kezd elfogyni a memória, akkor nézd meg, hogy az indításhoz képest melyik terület eszik sokat.
https://iotguru.cloud
detail opcióval próbáld, akkor lesznek részletek.
Annyi már most is látszik, hogy vannak Class-ok (objektumok), amik csak szaporodnak és nem szabadulnak fel.
Azok nem off-heap objektumok és az első pár órába üzemszerű, hogy szaporodnak. Itt valami az off-heap területet eszi.
https://iotguru.cloud
Köszönöm az eddigi segítségeteket.
2 további tapasztalat:
1. Ami viszont előjött, ha be van kapcsolva ez a -XX:NativeMemoryTracking akkor jobban eszi a memóriát. Így mos éppen az ellen-teszt megy. Azaz ennek a bekapcsolása nélkül igyekszem növelni a memórahasználatot. Egyelőre nem sikerült. :-(
2. Közben megnéztem az Eclipse mat-al és a YourKit-el is a memory dumpot. Az Mat-al az jött ki, hogy van 900m live object és van ~4.1G kitakarítandó objektum a heap-en.
- Ha csak a live memóriát nézem: 11 instances of "org.hibernate.internal.SessionFactoryImpl", loaded by "org.jboss.modules.ModuleClassLoader @ 0x7ef572f327d0" occupy 0,24 GB (27,56%) bytes.
- Ha a teljes heap-ot nézem, akkor a (azokat is figyelembe veszem, amiket a GC még nem takarított ki): 3 380 968 instances of "org.jboss.as.security.plugins.ModuleClassLoaderLocator$CombinedClassLoader", loaded by "org.jboss.modules.ModuleClassLoader @ 0x7ef571ea34c8" occupy 4,21 GB (56,06%) bytes.
Ez is elég furcsa viselkedés. Vagy nem G1-nél? Itt már nem tudom mekkora xmx volt megadva.
Akkor takarít intenzíven, amikor majdnem kifogy a memóriából, előtte minek strapálja magát? :)
https://iotguru.cloud
Köszönöm, akkor ez nem gond. Tovább tesztelek, hogy előidézzem a mem fogyást a teszt szerveren.
gyanus. db oldalon egy open connection graphot ratennek a mem trendre...
illetve szoritsd le a connection poolt h azzal lapos lesz -e ez a resz -e
Köszönöm. Tudunk róla, hogy ez a verziójú hibernate bizonyos esetekben több select-et futtat, de ez nem indokolja a mem fogyást.
Esetleg érdemes lenne egy memória analizálást is csinálni, hátha a kódban is változott valami, vagy előjött egy olyan eset, amivel eddig nem foglalkoztatok.
Ha van heap dump (esetleg több is, az még jobb) akkor ezzel az ingyenes tool-lal meg tudjátok nézni, hogy mi is a helyzet:
https://www.eclipse.org/mat/
Köszönöm. A hiba úgy tűnik a heap-en kívül van. Így ezt lehet később megnézem. De most egyelőre a heap-en kívüli memóriát igyekszem valahogy felderíteni.
Ó baszki, persze, mindent egyszerre, hogy esélyed ne legyen kideríteni, hogy mi baszódott el! Egyszerre csak egy komponenst érdemes elbaszni.
https://iotguru.cloud
Sajnos az egyik húzta maga után a másikat: WildFly upgrade -> Java upgrade, majd a környezetben változott dependenciáknak megfelelően igazítottuk a kódot.
Nem baj, de legalább már megint nem segített, csak utólag bölcselkedett.
Ja.
https://iotguru.cloud
hmap kilistázza milyen class-ból hány db van a memóriában és mennyit foglal
Igen. Ezt néztük a memory dump-al. 900 mega körül van az élő objektumok száma a 23G-ból.
https://www.yourkit.com/java/profiler/features/
Ez a tool nem vihet kozelebb a megoldashoz?
Eszi is a memóriát vagy csak úgy gondolod, hogy eszi? Van ebből a fajta szerverből még és azok nem csinálják, vagy egyedi szerver és/vagy egyedi konfigurációval?
https://iotguru.cloud
Köszönöm.
Eszi. Amikor kezdte elérni a fizikai memória határát, egyre lassabb is lett. Annyira lassú, hogy kénytelenek voltunk újraindítani.
Van több szerverünk is. De ebből 2-ő van, mindkettő ugyanazt produkálja.
A többi más alkalmazásainkkal futó szerveren is látunk hasonlót, de ott jóval lassabban eszi a memóriát. Napi 300-400-600 mega fogy a többi szerveren. De még bőven kereten belül vannak.
Ez meg 1 nap alatt feleszik 20G-át.
Az jo, akkor legalabb reprodukalhato.
java.nio kornyeken nezz korul, abban vannak bufferek, amik off-heap memoryt foglalnak. Valszleg valahol nem lesznek lezarva (vagy application code vagy wildfly code).
https://dzone.com/articles/troubleshooting-problems-with-native-off-hea…
https://dzone.com/articles/understanding-java-buffer-pool
Amugy lepjel vissza 1-2 wildfly verziot, ha lehetseges, hatha segit. Meg ugy altalaban is ajanlatos semmit nem hasznalni a wildfly-bol, ami nem public api module. Inkabb csomagold be a deploymentedbe a neked kello libet, es akkor nem fogsz szivni uj wildfly eseten.
Köszönöm. Ezeket is átolvasom. Egyelőre még egy fentebbi tippet nézek.
Gondolom 64 biten használod. 64 biten a java úgy működik, hogy befoglal egy egységes címtartományt, de memóriát nem. Igy lehet az, hogy azt látod, mintha megenne 10-20 gigát, pedig valójában
nem annyit eszik.
Ez esetleg segíthet:
https://www.ibm.com/support/pages/ibm-java-linux-how-reconciling-linux-…
Unixon malloc-ot hív, azzal a hátsó gondolattal, hogy 'a libc/kernel bizonyára rájön, hogy nem egészen komolyan gondolom...
a /proc alatt a megfelelő PID-nèl mi látható? érdemes lenne megmutatni a jól működőt is.
Itt elég sok dolog van. Pontosan mit nézzek?
maps, numa_maps, smaps (vagy smaps_rollup), status -> lehet, hogy ezekkel egy lépéssel sem kerülsz közelebb. talán segítenek, talán nem. mondanám, hogy próbálj egy strace-t az érintett PID-re, de ugyanaz a gond, vagy fog segíteni, vagy nem (de inkább nem). coredumpod van?
hprof dump-om van.
Viszont így elég nehéz lesz megtalálni a gondot:
1. A heapon kívül van.
2. ~10 ezer kérést kell beküldenem ahhoz, hogy 20 megát felzabáljon a non-heap. Ha bekapcsolom a natív mem figyelőt az többet eszik ennél.
Ennek ellenére a /proc/PID/ alatt nézd meg sima cattal, hogy az általam írt node-ok mit adnak vissza. Hátha.
Köszönöm. Egyedül a status fájlhoz volt jogom:
Ebből ami érdekes lehet:
VmLck: 0 kB
VmPin: 0 kB
VmHWM: 11907748 kB
VmRSS: 11897448 kB
RssAnon: 11873172 kB
RssFile: 24276 kB
RssShmem: 0 kB
VmData: 23113716 kB
VmStk: 132 kB
VmExe: 4 kB
VmLib: 26560 kB
VmPTE: 23872 kB
VmSwap: 0 kB
Threads: 171
Sajnos ebből semmi értelmeset nem tudok mondani. Köszönöm, hogy megnézted!
Ez a folyamatosan novekvo memoria hasznalat a JVM heap-en kivul eleg erost memoryleak-re utal. Az nem lenne baj, ha megenne az osszes memoriat, hiszen ez a dolga, csak kozben tisztitani is kellen (amennyiben a linux virtual memory-ban az adott page-ek felszabadithatoak lennenek, de ezek szerint nem lesznek azok).
Nem nagyon vagom a java-t en sem, de nalunk akkor szoktak belassulni a java alkalmazasok amikor a GC tul hosszu ideig, tul sokat kell takaritson. Mondjuk akkor a cpu usage is az egekben szokott lenni. De ha jol tudom a GC csak a jvm heap-et takaritja nem? Mondom nem ertek hozza.
En pmap-al is megneznem periodikusan a process virtual memory hasznalatat, hogy lassam hol novekszik a mi. Aztan ott a /proc/PID/smaps idonkenti leszedese es diffe-lgetese. Aztan vannak az inygenes tool-ok mtrace es tarsai. Tuti van valami a java-ra is.
na talaltam valamit:
https://dzone.com/articles/finding-java-memory-leaks-from-a-heap-dump
Esetleg:
https://github.com/inspectIT/inspectit-ocelot
Vagy
https://adoptopenjdk.net Jvm openj9 változatban érdemes lenne kipróbálni.
Egyáltalán milyen funkciója van az APP-nak?
Bookmark.
nincs benne vhol jni ami elkezdett leak-lni?
+1
Ha A directmemory kimutatásokban nem szerepel, akkor JNI leakelhet. Az ilyet a legnehezebb megfogni, ha ez bárkit megnyugtat :-).
Ha Java DirectMemory leakel, akkor az a Heap Dumpban látható lehet: A DirectByteBuffer típusú objektumok szaporodnak. (Vagy valami nio osztály, ha esetleg azok is foglalnak ilyen memóriát.) Ezt meg lehet a Heap Dump alapján találni.
Ha a natívak leakelnek, azt már nehezebb megtalálni.
fentebb irtam, en hibernate session jdbc driver native leaket tippelek
APA sort szeretek.
Köszönöm. A Direct memóriát már néztem így. Az akt dump-ban 125 mega volt összesen ami a Bufferek számai alapján látszott a non-heap-ból. Azaz nem magyarázta a gigákat.
subscribe.
Talisker Single Malt Scotch Whisky aged 10 years - o.k. Yamazaki is playing as well :)
esetleg a fejlesztoknek erdekes lehet az alabbi ket link:
https://dzone.com/articles/troubleshooting-problems-with-native-off-heap-memo
https://stackoverflow.com/a/53624438 (itt a Direct buffers bekezdes)
A G1 asszem kevésbé szereti felszabadítani a memóriát.
https://www.oracle.com/technical-resources/articles/java/g1gc.html
https://www.infoq.com/articles/tuning-tips-G1-GC/
gc-t vissza is lehetne allitani probabol a parallelre...
ha kidumpolod a 22 giga memót és nyomsz rá egy strings parancsot, lehet hogy ezerszer ismétlődni fog vmi nyom, akár jdbc driver, akár bármi más
subscribe
Nem nagyon hiszem hogy a 16g heap valid igény lenne, érdemes lenne sokkal kisebbel próbálkozni.
Akkor hamarabb elkezd aktívkodni a gc, kisebbek, kezelhetőbbek a dumpok.
Ha non-heap probléma van annak az arányai is jobban látszanak, hamarabb tolódik arra a memória igény.
Gábriel Ákos
metaspace, ami unlimited by default
leanykori neven PermGen
https://dzone.com/articles/java-memory-architecture-model-garbage-colle…
https://dzone.com/articles/java-8-permgen-metaspace
https://stackoverflow.com/questions/18339707/permgen-elimination-in-jdk…
Valtig allitom a hibernate es session classok csucsulnek ott mert nem engedi el a jpa a jdbc connection dolgok miatt :-)
Van valami jó kis session beragadás a wildfly-ban ami aztán minden egyebet is bent tart?
Végül is elég jó esély van rá, láttam ilyet, szerencsére nem mostanában :)
Gábriel Ákos
"szeretjuk a JPA kat"
https://github.com/by-pinja/wildfly-hibernate-leak
Egyelőre úgy tűnik JVM hibába futottunk. Egy új 11-es java telepítése ígéretesnek tűnik.
Érdekes. Melyik verzió melyik hibája ez? Linket szívesen néznék.
https://bugs.openjdk.java.net/browse/JDK-8230908
Köszi! Mi is utazunk Javában, és nem árt hallani ezekről. Jól értem, hogy az ilyen dinamikusan osztályokat generáló-betöltő-majd kidobó könyvtárakkal jön csak elő ez az issue?
Az is kiderült, hogy melyik könyvtár csinál ilyen nagytömegű osztálybetöltést, és mi célból?
jol gondolom hogy ez a symbols ott van ahol irtam a metaspace-ben. ok, nem hibernate de dynamic class ahogy irtam !:-) nem JPA hanem egy masik class dobalo csunyasag a Classloader:-)
milyen boldogság hogy ilyesmikre megy rá az embernek 1 hete :)
Ennél csak az jobb, amikor egy hülye és reprodukálhatatlan hibát nyomozol egy héten át, aztán végül megtalálod a problémás sort, felette pedig azt, hogy
https://iotguru.cloud
Odassatok! :)
JEP 387: Elastic Metaspace
Return unused HotSpot class-metadata (i.e., metaspace) memory to the operating system more promptly, reduce metaspace footprint, and simplify the metaspace code in order to reduce maintenance costs.
http://openjdk.java.net/jeps/387
érdemes beállítani a -XX:MaxMetaspaceSize= értéket hogy a gc dolgozhasson.....
https://cf-docs.jp-east-1.paas.cloud.global.fujitsu.com/en/manual/overv…
Persze ha bug van akkor be is lassulhat minden....