outofmemoryerror – czy to znaczy, że muszę kupić …...gerbage first...
Post on 27-Jun-2020
1 Views
Preview:
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 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://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