Memory dump - trigger po przekroczeniu ilości pamięci

0

Nie mam z tym za bardzo doświadczenia, zawsze był jakiś devops obok, który pomagał mi rozwiązywać takie problemy. Teraz jestem sam w projekcie i wolę was zapytać, bo często ktoś tu pomaga.

Opis problemu:
Jest to mała aplikacja, działająca na kontenerze używana przez 1-2 użytkowników(springboot & thymeleaf). Zwiększyliśmy pamięć na aplikację z 600mb do 1gb, bo wyrzucało nam OOM. Po podwyższeniu pamięci serwis działa, ale GC zaczął się odpalać dość często. Pamięć skacze jak na screenie. Większość zajmowanej pamięci to tenured space, który później spada do stabilnego poziomu.

Pytanie:
Jako, że nawet przy praktycznie zerowych requestach i braku jakichkolwiek shedulerów na tym serwisie takie skoki występują, chciałbym zrobić memory dump w okresie wzrostu pamięci. Stąd pytanie: da się zrobić trigger, który uruchomi tworzenie memory dumpa po przekroczeniu, np. 800mb?
Może w złym miejscu szukam powodu? Wszystkie wskazówki przyjmę z pokorą :). Pozdrawiam
screenshot-20210427112107.png

0

na zegarku to odpalacie? Bałbym się odpalić apkę Springową z mniejszą ilością pamięci niż 2GB. A co do Twojego pytania to nie wiem czy da się ustawić trigger na konkretną wartość pamięci, na pewno da się, jak już stuknie OOM.

4

java -XX:+HeapDumpOnOutOfMemoryError -XX:HeapDumpPath=<file-or-dir-path> to najprostszy sposób.
Mam webowe apki co zajmują 250mb - 400mb (aby płacić mniej za chmurkę) i jakoś to działa. (ale nie springowe).
Spring WebFlux funkcyjny też się w 300mb z całkiem wypasionym backendem (pod względem funkcji) mieścił. Z jednej strony w webflux nie ma tomcata, ale
zdrugiej strony programowanie funkcyjne nie jest znane z tego, że oszczednie gospodaruje pamięcią.

Oczywiście zakładam, że -Xmx ustawiacie. Skoki w ramach całego udostępnionego Xmx to normalka - tak działa gc.
Problemy to nagłe przyrosty w metaspace / nonheap albo w old (tenured).
Problem to również cały czas pamięć zajęta pod kurek.
Trzeba zobaczyć ile procentowo zajmuje GC (procent CPU) - to zwykle łatwa statystyka do wyciągniecia (jconsole itp).
Jak to jest poniżej 10% to zwykle można przyjąć, że działa jak powinno. Jak więcej - to coś jest nie tak z ustawieniami, albo kodem aplikacji.

1

Radzę się zapoznać:

  • 1GB to śmiesznie mały heap. U Ciebie wygląda jakby jakiś request zjadał naglę z 0.5 GB pamięci. To co @jarekr000000 podał jest jak najbardziej OK, taki heap można potem przeanalizować darmowym MAT'em (https://www.eclipse.org/mat/) lub płatnym YourKit'em.

Na moje oko heap jest po prostu za mały. Warto też puszczać na JDK 11 nawet jak było skompilowane pod JDK 8.

2
  1. E tam przesadzacie, odpalałem springowe apki z 32MB heapu :P
  2. Pytanie brzmi: co się (biznesowo) dzieje kiedy masz te skoki? Popatrz w logi aplikacji albo w inne metryki (requesty http?)
  3. Generalnie to jest normalne ze heap rośnie pod limit a potem leci GC. Stąd często masz taki wykres jak "piła", ale u ciebie masz ewidentnie jakieś nagłe skoki i to zgodnie z zegarkiem.
0

Dziękuję za wszystkie odpowiedzi, dzisiaj wróciłem do tematu i obniżyłem poziom logów na debug w celu analizy. Okazało się, że po restarcie aplikacji wszystko wróciło do normy, nie ma spików <shrug>. Pozostawiam póki co serwis na obserwację :)

Co do małej ilości ram.. wszystkie serwisy, które mamy chodzą na min 600mb, a max 1.5gb(ale mamy ich kilka instancji) przy sporej ilości użytkowników działa to całkiem nieźle, więc opinie o tym, żeby na aplikację springa 2gb uważam za przesadzone. Może pisząc to macie na myśli jakieś większe aplikacje/monolity.

@0xmarcin dzięki za materiał, przestudiuję :)

@jarekr000000 tak, java optsy mamy ustawione. Jeśli sytuacja będzie się powtarzać, to wrócę do Twoich sugestii. Dzięki!

3

Deployować, obserwować.

1 użytkowników online, w tym zalogowanych: 0, gości: 1