Aplikacja zwalnia z czasem

Aplikacja zwalnia z czasem
VO
  • Rejestracja: dni
  • Ostatnio: dni
  • Postów: 43
0

Mam taki problem, dostaje tablice byte po Socket'ach TCP. Dane te parsuje przez refleksje na konkretne obiekty które następnie trafiają do bazy.

  1. Watek odbiera dane z TCP wrzuca te dane na kolejkę dyskowa
  2. Watek ściąga z kolejki dyskowej parsuje dane refkleksja zapisuje
    Problem jest taki ze jak system przez dłuższy czas jest mocno obciążony to z czasem co raz bardziej zwalnia mimo ze intensywność wysyłania danych do tej aplikacji jest ciągle taka sama.
    Wycieków pamięci brak...

Na co zwrócić uwagę?

Shalom
  • Rejestracja: dni
  • Ostatnio: dni
  • Lokalizacja: Space: the final frontier
  • Postów: 26433
1

Wycieków pamięci brak...

press X to doubt ;)

Trudno coś poradzić nie widząc w ogole kodu. Odpal sobie VisualVM i zobacz czy faktycznie gdzieś coś nie cieknie. Zalecałbym też używać metryk w kodzie, jakiś micrometer czy coś w tym stylu. Jeśli to jakaś produkcyjna aplikacja to warto mieć! Wrzucasz sobie w interesujące miejsce jakieś timery i widzisz gołym okiem na ładnych wykresach w grafanie które czasy rosną chociażby.
Może masz gdzieś jakieś liniowe przeszukiwanie / operacje zależne od ilości przetworzonych danych?

refleksje na konkretne obiekty

Ale nie robisz tam jakichś cudow w stylu tworzenia klas (nie obiektów) w runtime na przykład? Bo to by mogło mieć takie efekty.

Przy okazji, czemu nie jakiś protobuf albo jakaś bardziej ludzka metoda zamiast ręcznego dziergania refleksją?

VO
  • Rejestracja: dni
  • Ostatnio: dni
  • Postów: 43
0

Co do VisualVM i tym podobnych już były wykorzystane. Co do kodu niestety nie mogę go ujawniać (firmowy kod).
Dekodowanie tych danych niestety mamy załatwione refleksją w krokach:

  1. Znajdź delimiter w odebranych danych
  2. Na podstawie delimitera wiem jaki to obiekt
  3. Tworze instancję obiektu
  4. Lecimy refleksją po polach obiektu i wyciagamy wartości pól z odebranych danych
  5. Jeśli pole jest listą obiektów to lecimy 1,2,3,.. pseudo "rekurencja" (oczywiście długość list mamy w wartości int pola poprzedzającego liste itd.
    Dane które przychodzą po tcp mają swój określony format tzn wartość pola INT nie koniecznie musi być zapisana na 4 bajtach a np. jedynie na 2 itp. zaleznie od deklaracji ilosci bajtow w konrketnym obiekcie (taki mamy narzut :P )
Charles_Ray
  • Rejestracja: dni
  • Ostatnio: dni
  • Postów: 1910
1

Można wróżyć z fusów, ja bym sprawdził:

  1. Indeksy i locki na bazie
  2. Co robią wątki? Jeśli jest lock na bazie to będą czekać na I/O. Może wątki są zajęte, ale zadania trafiają na kolejkę puli wątków.
  3. gc logi - ile czasu aplikacja spędza na GC, czy nie ma wycieku pamięci
VO
  • Rejestracja: dni
  • Ostatnio: dni
  • Postów: 43
0
Charles_Ray napisał(a):

Można wróżyć z fusów, ja bym sprawdził:

  1. Indeksy i locki na bazie
  2. Co robią wątki? Jeśli jest lock na bazie to będą czekać na I/O. Może wątki są zajęte, ale zadania trafiają na kolejkę puli wątków.
  3. gc logi - ile czasu aplikacja spędza na GC, czy nie ma wycieku pamięci

1,2 - Zapis juz sprawdzony (jest wąskie gardło ale czas zapisu jest ciagle na jednym poziomie)
3. Sprawdzone brak wycieków, GC na bieżąco czyści pamięć, czasy różne ale raczej nie przekraczają 1s

Charles_Ray
  • Rejestracja: dni
  • Ostatnio: dni
  • Postów: 1910
0

Może jeszcze jakieś synchronized dzikie w kodzie?

Shalom
  • Rejestracja: dni
  • Ostatnio: dni
  • Lokalizacja: Space: the final frontier
  • Postów: 26433
1

No to ja dalej postuluje wrzucenie timerów do kodu. Przyda wam się i tak bo fajnie mieć jakieś metryki ;) Takie timery przynajmniej pokażą konkretnie gdzie coś zwalnia i będzie wiadomo gdzie patrzeć.

VO
  • Rejestracja: dni
  • Ostatnio: dni
  • Postów: 43
0

Jedną z rzeczy jaką zauważyłem w visualVM że JPA przy wykonywaniu persist dostając gotowy obiekt do zapisu wywołuje domyślny konstruktor tej klasy i widać że tworzy jakąś swoją instancję tego obiektu.
Po co to robi jak dostaje gotowy obiekt? Pytam bo w konstruktorze mamy dość skomplikowaną logikę która niepotrzebnie jest odpalana przy zapisie i podwyższa zużycie procka...

Shalom
  • Rejestracja: dni
  • Ostatnio: dni
  • Lokalizacja: Space: the final frontier
  • Postów: 26433
1

@volau bo JPA najpierw robi obiekt który jest attached do sesji bazy danych, bo przecież przekazujesz coś w stanie detached. Nie może użyc tego obiektu który przekazałeś, bo jakby tam był jakiś współbieżny dostęp to by wszystko mogło wybuchnąć dość spektakularnie. Tak jest wg specyfikacji JPA -> zobacz że merge w EntityManagerze zwraca ci obiekt -> to jest właśnie ta kopia w stanie attached. Nie da sie tego za bradzo obejść, bo tak to po prostu zostało zaprojektowane.

Charles_Ray
  • Rejestracja: dni
  • Ostatnio: dni
  • Postów: 1910
1

A propos JPA jeszcze, to nie puchnie Ci persistence context? Nie wczytujesz dużej liczby obiektów w jednej transakcji?

VO
  • Rejestracja: dni
  • Ostatnio: dni
  • Postów: 43
0
Charles_Ray napisał(a):

A propos JPA jeszcze, to nie puchnie Ci persistence context? Nie wczytujesz dużej liczby obiektów w jednej transakcji?

Mieliśmy jakiś czas temu że odkładało sporo w cache'u JPA ale teraz mamy clear po kazdym zapisie paczki.
Po zrzucie pamięci nie wygląda obecnie żeby jakoś to puchło.
W zachowaniu GC widać że pamieć dochodzi do jakiegoś poziomu i wchodzi GC i pamieć spada. Używamy GC1 z flagą server.
Jeśli chodzi o odczyt to akurat w tej aplikacji go nie ma jest ona odpowiedzilna za walidacje odebranych danych i tylko zapis na baze.

jarekr000000
  • Rejestracja: dni
  • Ostatnio: dni
  • Lokalizacja: U krasnoludów - pod górą
  • Postów: 4712
0
volau napisał(a):

Co do VisualVM i tym podobnych już były wykorzystane.

Zrobiliście CPU profiling visualvm-em i nadal nie wiadomo co jest konkretnie powolne?
Potencjalnie możliwe, ale naprawdę trzeba by mieć niezłego pecha, zwłaszcza w tak prostej aplikacji.
Zdecydowanie polecam nie wstawianie własnych timerów tylko naukę / praktyckę cpu profilingu.
timery kłamią bardzo, szczególnie w aplikacjach wielowątkowych,
cpu profilery kłamią również bardzo, ale da się je na tym kłamstwie przyłapać (ustawiając rózne starting points, oraz porównując z CPU samplingiem).

Zarejestruj się i dołącz do największej społeczności programistów w Polsce.

Otrzymaj wsparcie, dziel się wiedzą i rozwijaj swoje umiejętności z najlepszymi.