outofmemoryerror – czy to znaczy, że muszę kupić …...gerbage first...

Post on 27-Jun-2020

1 Views

Category:

Documents

0 Downloads

Preview:

Click to see full reader

TRANSCRIPT

mateusz.herbut@gmail.com

OutOfMemoryError – czy to znaczy, że muszę kupić więcej pamięci?

Sekcje pamięci JVM i typy Garbage Collector'ów Ile pamięci zajmuje nasz obiekt? OutOfMemoryError

czyli pora powiększyć stertę Compressed OOPs

czyli jakim cudem za pomocą 32-bitowego wskaźnika jesteśmy w stanie zaadresować 64GB pamięci

Co robić, gdy wycieka nam pamięć Przydatne narzędzia Case study – Hello Leak

Agenda

Źródło grafiki: https://blog.codecentric.de/en/2010/01/the-java-memory-architecture-1-act/

Sterta i stos

Źródło grafiki: http://www.radio90.pl/files/2013/06/smieci-4.jpg

Kolekcjoner śmieci

Źródło grafiki: https://blog.codecentric.de/en/2010/01/the-java-memory-architecture-1-act/

Sterta HotSpot'a

Źródło grafiki: http://www.filmweb.pl/film/%C5%BBy%C4%87+szybko,+umiera%C4%87+m%C5%82odo-2002-32901

Sterta HotSpot'a

Źródło grafiki: https://blog.codecentric.de/en/2010/01/the-java-memory-architecture-1-act/

Sterta HotSpot'a

-XX:-PrintGCDetails

-XX:+UseSerialGC

Throughput collectors:

-XX:+UseParallelGC -XX:ParallelGCThreads=<desired number> -XX:MaxGCPauseMillis -XX:GCTimeRatio

-XX:+UseParallelOldGC

low pause collector:

-XX:+UseConcMarkSweepGC -XX:ParallelCMSThreads=2

Źródło grafiki: https://blog.codecentric.de/en/2010/01/the-java-memory-architecture-1-act/

Sterta HotSpot'a

-Xms<size> początkowy rozmiar sterty

-Xmx<size> maksymalny rozmiar sterty

-Xss<size> rozmiar stosu

-XX:PermSize<size> rozmiar Perm

-XX:MaxPermSize<size> maksymalny rozmiar Perm

-Xmn<size> rozmiar Eden

Źródło grafiki: https://blog.codecentric.de/en/2010/01/the-java-memory-architecture-1-act/

Sterta HotSpot'a

-XX:NewRatio<ratio> Tenured/Young

-XX:SurvivorRatio<ratio> Eden/Survivor

-XX:MinHeapFreeRatio<ratio> Minimalna ilość wolnego miejsca (w %) po działaniu GC zapobiegająca ekspansji sterty

-XX:MaxHeapFreeRatio<ratio> Maksymalna ilość wolnego miejsca (w%) po działaniu GC zapobiegająca skurczeniu sterty

Źródło grafiki: http://plock.gazeta.pl/plock/1,35710,14158417,Ministerstwo__Nie_ma_kar_za_niezlozenie_deklaracji.html

Ustawa śmieciowa

Źródło grafiki: https://blog.codecentric.de/en/2010/01/the-java-memory-architecture-1-act/

Odbierajmy śmieci częściej!

Źródło grafiki: https://blog.codecentric.de/en/2010/01/the-java-memory-architecture-1-act/

Odbierajmy śmieci częściej!

Źródło grafiki: http://www.oracle.com/webfolder/technetwork/tutorials/obe/java/G1GettingStarted/index.html

Gerbage First Collector

G1 zapewnia wysoką prepustowość (throughput), kompaktuje sterte

Źródło grafiki: http://www.oracle.com/webfolder/technetwork/tutorials/obe/java/G1GettingStarted/index.html

Gerbage First Collector-XX:+UseG1GC

-XX:MaxGCPauseMillis=200 – to tylko sugestia

-XX:InitiatingHeapOccupancyPercent=45 – kiedy zacząc GC

-XX:NewRatio=n Ratio new/old (domyślnie 2)

-XX:SurvivorRatio=n Ratio eden/survivor (domyślnie 8)

-XX:MaxTenuringThreshold=n (domyślnie 15)

-XX:ParallelGCThreads=n

-XX:ConcGCThreads=n

-XX:G1HeapRegionSize=n 1M-32Mb, domyślnie JVM

wybierze optymalną wartość

Źródło grafiki: http://www.oracle.com/webfolder/technetwork/tutorials/obe/java/G1GettingStarted/index.html

Gerbage First Collector-XX:+UseG1GC

-XX:MaxGCPauseMillis=200 – to tylko sugestia

-XX:InitiatingHeapOccupancyPercent=45 – kiedy zacząc GC

-XX:NewRatio=n Ratio new/old (domyślnie 2)

-XX:SurvivorRatio=n Ratio eden/survivor (domyślnie 8)

-XX:MaxTenuringThreshold=n (domyślnie 15)

-XX:ParallelGCThreads=n

-XX:ConcGCThreads=n

-XX:G1HeapRegionSize=n 1M-32Mb, domyślnie JVM

wybierze optymalną wartość

-Xmn<size> - rozmiar Edenu

Ile pamięci potrzebuje obiekt?

//8B for object headerpublic class ClassWithLong {

//8B for longprivate long long_ = 258L;

}//total = 16 B

Ile pamięci potrzebuje obiekt?

//8B for object headerpublic class ClassWithLong {

//8B for longprivate long long_ = 258L;

}//total = 16 B

//8B for object headerpublic class ClassWithInt {

//4B for intprivate int int_ = 258;

}//total = ?

Ile pamięci potrzebuje obiekt?

//8B for object headerpublic class ClassWithLong {

//8B for longprivate long long_ = 258L;

}//total = 16 B

//8B for object headerpublic class ClassWithInt {

//4B for intprivate int int_ = 258;

}//total = 12B + 4B of alignment = 16B

Ile pamięci potrzebuje obiekt?

//8B for object headerpublic class ClassWithLong {

//8B for longprivate long long_ = 258L;

}//total = 16 B

//8B for object headerpublic class ClassWithInt {

//4B for intprivate int int_ = 258;

}//total = 12B + 4B of alignment = 16B

//8B for object headerpublic class ClassWithBoolean {

//1B for booleanprivate boolean bool = false;

}

//total = ?

Ile pamięci potrzebuje obiekt?

//8B for object headerpublic class ClassWithLong {

//8B for longprivate long long_ = 258L;

}//total = 16 B

//8B for object headerpublic class ClassWithInt {

//4B for intprivate int int_ = 258;

}//total = 12B + 4B of alignment = 16B

//8B for object headerpublic class ClassWithBoolean {

//1B for booleanprivate boolean bool = false;

}

//total = 9B + 7B of alignment = 16B

Ile pamięci potrzebuje obiekt?

//8B for object headerpublic class ClassWithLong {

//8B for longprivate long long_ = 258L;

}//total = 16 B

//8B for object headerpublic class ClassWithInt {

//4B for intprivate int int_ = 258;

}//total = 12B + 4B of alignment = 16B

//8B for object headerpublic class ClassWithBoolean {

//1B for booleanprivate boolean bool = false;

}

//total = 9B + 7B of alignment = 16B

//8B for object header//8B for superClass fieldspublic class ClassExtends16B extends ClassWithLong {

//8B for longprivate long long2 = 258L;

}

//total = 24 B

Ile pamięci potrzebuje obiekt?

//8B for object headerpublic class ClassWithLong {

//8B for longprivate long long_ = 258L;

}//total = 16 B

//8B for object headerpublic class ClassWithInt {

//4B for intprivate int int_ = 258;

}//total = 12B + 4B of alignment = 16B

//8B for object headerpublic class ClassWithBoolean {

//1B for booleanprivate boolean bool = false;

}

//total = 9B + 7B of alignment = 16B

//8B for object header//8B for superClass fieldspublic class ClassExtends16B extends ClassWithLong {

//8B for longprivate long long2 = 258L;

}

//total = 24 B

//8B for object header//1B? or 8B? for superClass fieldspublic class ClassExtends9B extends ClassWithBoolean {

//4B for intprivate int int_ = 258;

}

Ile pamięci potrzebuje obiekt?

//8B for object headerpublic class ClassWithLong {

//8B for longprivate long long_ = 258L;

}//total = 16 B

//8B for object headerpublic class ClassWithInt {

//4B for intprivate int int_ = 258;

}//total = 12B + 4B of alignment = 16B

//8B for object headerpublic class ClassWithBoolean {

//1B for booleanprivate boolean bool = false;

}

//total = 9B + 7B of alignment = 16B

//8B for object header//8B for superClass fieldspublic class ClassExtends16B extends ClassWithLong {

//8B for longprivate long long2 = 258L;

}

//total = 24 B

//8B for object header//1B for superClass fieldspublic class ClassExtends9B extends ClassWithBoolean {

//4B for intprivate int int_ = 258;

}

//total = 13B + 3B of alignment = 16B

Źródło grafiki: http://g-ec2.images-amazon.com/images/G/01/dvd/sony/MIB32L._V401281254_.jpg

OutOfMemoryError

Źródło grafiki:http://diylol.com/

W takim razie zwiększmy pamięć

Źródło grafik: http://www.naszekielce.com/sites/default/files/S6302409.jpg, http://diylol.com/

W takim razie zwiększmy pamięć

Źródło grafiki:http://diylol.com/

W takim razie zwiększmy pamięć

„If you have a larger room to clean then it tends to take more time for the janitor to clean the room. The very same applies to cleaning unused objects from memory. When running applications on small heaps (below 4GB) you often do not need to think about GC internals. But when increasing heap sizes to tens of gigabytes you should definitely be aware of the potential stop-the-world pauses induced by the full GC. The very same pauses did also exist with small heap sizes, but their length was significantly shorter – your pauses that now last for more than a minute might have originally spanned only a few hundred milliseconds.”

[http://plumbr.eu/blog/increasing-heap-size-beware-of-the-cobra-effect]

Za pomocą 32-bitowego wskaźnika możemy zaadresować 2^32 bajtów, czyli 4GB

W praktyce, pod kontrolą 32 bitowego OSa mamy dostępną mniejszą pulę pamięci (~1,5GB w 32-bitowym Windowsie , 2GB w 32-bitowym Solaris).

W 64-bitowych OSach z 32 bitową Javą mamy do dyspozycji 4GB

Pamięć też ma swoje granice

Gdy potrzebujesz więcej niż 4GB, musisz użyć 64 bitowej JVM

Pamięć też ma swoje granice

Gdy potrzebujesz więcej niż 4GB, musisz użyć 64 bitowej JVM

… wtedy nagłówek klasy zajmuje 12B, zamiast 8B …

Pamięć też ma swoje granice

Gdy potrzebujesz więcej niż 4GB, musisz użyć 64 bitowej JVM

… wtedy nagłówek klasy zajmuje 12B, zamiast 8B …

… a (prawie) każda referencja 8 B, zamiast 4B

Pamięć też ma swoje granice

Gdy potrzebujesz więcej niż 4GB, musisz użyć 64 bitowej JVM

… wtedy nagłówek klasy zajmuje 12B, zamiast 8B …

… a (prawie) każda referencja 8 B, zamiast 4B

„The performance difference comparing an application running on a 64-bit platform versus a 32-bit platform on SPARC is on the order of 10-20% degradation when you move to a 64-bit VM. On AMD64 and EM64T platforms this difference ranges from 0-15% depending on the amount of pointer accessing your application performs.”

Pamięć też ma swoje granice

[http://www.oracle.com/technetwork/java/hotspotfaq-138619.html]

-XX:+UseCompressedOops

OrdinaryObject Pointers

-XX:+UseCompressedOops

Pamięć do 4GB może być zaadresowana 32-bitowym wskaźnikiem (2^32B = 4GB)

OrdinaryObject Pointers

-XX:+UseCompressedOops

Pamięć do 4GB może być zaadresowana 32-bitowym wskaźnikiem (2^32B = 4GB)

Każdy obiekt na stercie zaczyna się co 8 bajtów. Nie potrzebujemy adresu do każdego bajta – potrzebujemy adresu do każdego oktetu bajtów. Stąd jesteśmy w stanie zaadresować 8 razy więcej pamięci => 32 GB

OrdinaryObject Pointers

-XX:+UseCompressedOops

Pamięć do 4GB może być zaadresowana 32-bitowym wskaźnikiem (2^32B = 4GB)

Każdy obiekt na stercie zaczyna się co 8 bajtów. Nie potrzebujemy adresu do każdego bajta – potrzebujemy adresu do każdego oktetu bajtów. Stąd jesteśmy w stanie zaadresować 8 razy więcej pamięci => 32 GB

A gdyby każdy obiekt zaczynał się co 16 bajtów? Wtedy możemy zaadresować 64 GB

OrdinaryObject Pointers

-XX:+UseCompressedOops

Pamięć do 4GB może być zaadresowana 32-bitowym wskaźnikiem (2^32B = 4GB)

Każdy obiekt na stercie zaczyna się co 8 bajtów. Nie potrzebujemy adresu do każdego bajta – potrzebujemy adresu do każdego oktetu bajtów. Stąd jesteśmy w stanie zaadresować 8 razy więcej pamięci => 32 GB

A gdyby każdy obiekt zaczynał się co 16 bajtów? Wtedy możemy zaadresować 64 GB*

OrdinaryObject Pointers

*takie rzeczy tylko od jdk7 lub jRockitR28

Źródło grafik: http://www.zywienieczlowieka.pl/web_images/chudzielec.jpg, http://c.wrzuta.pl/wi867/abe5ce6400215f574880cca2/grubas

CompressedOops

64 GB

32 GB

Źródło grafik: http://www.zywienieczlowieka.pl/web_images/chudzielec.jpg, http://c.wrzuta.pl/wi867/abe5ce6400215f574880cca2/grubas

CompressedOops

64 GB

32 GB

84 GB

42 GB

Źródło grafiki: http://geek-and-poke.com/

Wycieki pamięci

Źródło grafiki: http://g-ec2.images-amazon.com/images/G/01/dvd/sony/MIB32L._V401281254_.jpg

OutOfMemoryError

-XX:+HeapDumpOnOutOfMemoryError

-XX:HeapDumpPath=<path>

jps + jmap + jhat + jstat

Visual VM

Eclipse Memory Analyzer (MAT) http://www.eclipse.org/mat/

Oracle JRockit Mission Control - Memory Leak Detector

https://github.com/shipilev/java-object-layout

Toolsfor fools

Aplikacja w każdej iteracji: odbiera dane od dwóch data providerów i zapisuje je na

dwóch listach zlicza ilość wystąpień danych obiektów za pomocą

HashMapy zrzuca dane z HashMapy na dysk

Każda nowa iteracja jest niezależna od poprzedniej!

Demo

Demo

http://www.oracle.com/webfolder/technetwork/tutorials/obe/java/gc01/index.html

http://www.oracle.com/technetwork/java/javase/tech/vmoptions-jsp-140102.html

http://www.oracle.com/webfolder/technetwork/tutorials/obe/java/G1GettingStarted/index.html

http://docs.oracle.com/javase/7/docs/technotes/guides/vm/G1.html

http://www.drdobbs.com/jvm/g1-javas-garbage-first-garbage-collector/219401061?pgno=1

http://www.infoq.com/presentations/JVM-Performance-Tuning-twitter

http://plumbr.eu/blog

https://wikis.oracle.com/display/HotSpotInternals/CompressedOops

https://blogs.oracle.com/jrockit/entry/understanding_compressed_refer

http://eclipsesource.com/blogs/2013/01/21/10-tips-for-using-the-eclipse-memory-analyzer

http://herbi-blog.blogspot.com/2013/06/zarzadzanie-pamiecia-w-javie-oraz.html

Przydatne linki

mateusz.herbut@gmail.com

Pytania?

top related