Herhangi bir Java sınıfından new operatörü ile bir nesne oluşturulduğunda, bu nesnenin bilgisayarın hafızasında konuşlandırıldığı alana Java Heap adı verilir.
Java Heap JVM tarafından oluşturulur ve aşağıdaki hafıza alanlarından oluşur:
- Eden – new operatörü ile oluşturulan tüm nesneler önce bu hafıza alanında oluşturulur.
- Survivor – nesneler old heap hafıza alanına transfer edilmeden önce bir müddet survivor hafıza alanlarında kalır. Buradaki amaç kısa ömürlü olan nesnelerin Garbage Collector tarafından toplanmasına ve old heap alanına geçmelerini engellemektir.
- Old – uzun ömürlü nesnelerin ölene kadar kaldıkları hazıfa alanıdır.
- Permanent – sınıfların ve statik değerlerin yer aldığı hazıfa alanıdir.
Yukarda yer alan resime baktığımızda JVM tarafından yönetilen hafıza alanının (Java Heap) toplamda 5 GB olduğunu, bunun 1 GB’lik gibi bir kısmının EDEN Heap space, 150 MB’sinin iki SURVIVOR Heap Space ve 4 GB’sinin OLD Heap space tarafından kullanıldığını görmekteyiz. Toplamda JVM’in yönettiği ve içinde Java nesneleri oluşturabileceğimiz alan 5 GB büyüklüktedir.
BT Sözlüğü kategorisinden son yazılar
- İzci kuralı - August 20th, 2012
- JVM (Java Virtual Machine) Nedir? - May 12th, 2012
- Write Through Cache - December 21st, 2009
- YAGNI - November 17th, 2009
- KISS - Keep It Stupid Simple - November 17th, 2009
- DRY - Don't Repeat Yourself - November 17th, 2009
mabulgu
14 Mayıs 2012Yazı için teşekkürler hocam. Kullandığınız izleme aracının adı nedir acaba?
Özcan Acar
14 Mayıs 2012http://visualvm.java.net/
VisualGC plugini kurmak gerekiyor.
mabulgu
15 Mayıs 2012Teşekkürler.
Pingback: Çöplerin Efendisi - Kurumsal Java Yazılımı - Özcan Acar
Kenan
21 Haziran 2012Merhaba,
5GB Java Heap alanına göre Permanent için ideal min/max (PermSize/MaxPermSize) değerleri ne olmalıdır sizce?
Teşekkürler
Özcan Acar
21 Haziran 20125 GB gibi büyük hafiza alanlari icin hicbir JVM ayari yapilmamalidir. JVM zaman icinde kendisi icin gerekli optimal alan tahsis ayarlarini kesfedip, adaptif ayarlama yapacaktir.
Kenan
21 Haziran 2012Cevap için teşekkürler.
Çalışan sistemimizin -XX:+PrintGCDetails ile bastığı logları incelerken anormal bir durumla ile karşılaştım.
Sistemde 6 gündür GC loglarını yazdırıyoruz. Kullanılan toplam memory de bu süre içinde sürekli 3GB seviyelerinde idi. Sistem dün 18-20 saniye içinde Tenured Heap alanı 1GB seviyelerinden 4GB seviyelerine çıkmış. 6144MB toplam heap alanının tamamını kullanıyor görünüyordu. Sistemin yaptığı onca GC ve Full GC lerin hiç bir faydası olmamış. Önceki günlerde hiç böyle bir şey olmamış. Daha sonra da PemGen space hataları ve akabinde sistem çalışmaya devam etmemiş.
Sistem Linux makine üzerinde çalışıyor ve Tomcat -Xmx6144m ile başlıyor.
Tomcat 5.5
Java HotSpot(TM) 64-Bit Server VM (build 1.5.0_22-b03, mixed mode)
Özcan Acar
21 Haziran 2012Full GC ile tunered heap kücülmüyorsa o zaman ya memory leak var demektir. Bir heap dump alarak tunered space icinde ne olduguna bakmanizda fayda var.
Kenan
21 Haziran 2012Teşekkürler yanıtınız için,
Catalina yı -Xmx6144m ve GC print etmesi için gerekli parametreler ile başlatıyoruz. İlave başka parametre tanımlamayı önerir misiniz?
486604.886 zamanında (3299456K) Heap kullanırken 486622.509 ( sadece 18 saniye sonra )zamanında da (6014848K) heap kullanıyor.
Bu memory leak ten kaynaklanıyorsa ne önerirsiniz? Sistemde nasıl bir şey böyle bir sıçramaya sebep olabilir.
Dilerseniz size tüm GC log u gönderebilirim.
Bahsettiğim log un sorunun başladığı kısmı:
486551.289: [GC [PSYoungGen: 1751353K->18898K(1906304K)] 2036117K->303663K(3314496K), 0.0284620 secs]
486604.886: [GC [PSYoungGen: 1242648K->17197K(1891264K)] 1527413K->301962K(3299456K), 0.0159320 secs]
486604.902: [Full GC [PSYoungGen: 17197K->0K(1891264K)] [PSOldGen: 284764K->275121K(1600448K)] 301962K->275121K(3491712K) [PSPermGen: 86015K->86005K(86016K)], 0.4675960 secs]
486605.372: [GC [PSYoungGen: 418K->224K(1899776K)] 275539K->275345K(3500224K), 0.0045340 secs]
486605.377: [Full GC [PSYoungGen: 224K->0K(1899776K)] [PSOldGen: 275121K->275123K(1845632K)] 275345K->275123K(3745408K) [PSPermGen: 86011K->86011K(86016K)], 0.3582520 secs]
486605.735: [GC [PSYoungGen: 0K->0K(1889088K)] 275123K->275123K(3734720K), 0.0048360 secs]
486605.740: [Full GC [PSYoungGen: 0K->0K(1889088K)] [PSOldGen: 275123K->272151K(2136576K)] 275123K->272151K(4025664K) [PSPermGen: 86011K->85989K(86016K)], 0.3854400 secs]
486606.128: [GC [PSYoungGen: 2685K->355K(1897856K)] 274837K->272507K(4034432K), 0.0049500 secs]
486606.133: [Full GC [PSYoungGen: 355K->0K(1897856K)] [PSOldGen: 272151K->272331K(2489152K)] 272507K->272331K(4387008K) [PSPermGen: 86014K->86014K(86016K)], 0.3700000 secs]
486606.503: [GC [PSYoungGen: 0K->0K(1885056K)] 272331K->272331K(4374208K), 0.0047950 secs]
486606.508: [Full GC [PSYoungGen: 0K->0K(1885056K)] [PSOldGen: 272331K->268656K(2908096K)] 272331K->268656K(4793152K) [PSPermGen: 86014K->85989K(86016K)], 0.4767220 secs]
486621.089: [GC [PSYoungGen: 991523K->2723K(1750720K)] 1260179K->271380K(4658816K), 0.0072870 secs]
486621.096: [Full GC [PSYoungGen: 2723K->0K(1750720K)] [PSOldGen: 268656K->270726K(3416640K)] 271380K->270726K(5167360K) [PSPermGen: 86015K->86015K(86016K)], 0.5116610 secs]
486621.608: [GC [PSYoungGen: 0K->0K(1878144K)] 270726K->270726K(5294784K), 0.0050660 secs]
486621.613: [Full GC [PSYoungGen: 0K->0K(1878144K)] [PSOldGen: 270726K->267291K(4021120K)] 270726K->267291K(5899264K) [PSPermGen: 86015K->85984K(86016K)], 0.4995470 secs]
486622.124: [GC [PSYoungGen: 1481K->288K(1883136K)] 268772K->267579K(5904256K), 0.0310730 secs]
486622.155: [Full GC [PSYoungGen: 288K->0K(1883136K)] [PSOldGen: 267291K->267390K(4144064K)] 267579K->267390K(6027200K) [PSPermGen: 85993K->85993K(86016K)], 0.3540370 secs]
486622.509: [GC [PSYoungGen: 0K->0K(1870784K)] 267390K->267390K(6014848K), 0.0053390 secs]
Özcan Acar
22 Haziran 2012Göndermis oldugunuz logda hicbir sorun görünmüyor. mx parametresi yaninda ms parametresini de kullanmadiginiz icin JVM zaman icinde heap alanini verdiginiz 6144m’ye kadar yükseltiyor. JVM’in bu alani büyütebilmesi icin Full GC yapmasi gerekiyor. Asagida her Full GC’den sonra toplam heap alanini nasil büyüdügü görülmekte:
(3491712K)
(3745408K)
(4025664K)
(4387008K)
(4793152K)
(5167360K)
(5899264K)
(6027200K)
JVM verdiginiz limit olan 6144MB’de büyüme islemini durduracak.
JVM’in hemen 6GB alani heap olarak alabilmesi icin asagidaki sekilde olmasi lazim:
-Xms6144m -Xmx6144m
En son Full GC’ye baktiginizda (486622.155) kullanilan heap alani toplamda 267579K, yan 267MB civari. Eger uygulamanizda bir memory leak olsaydi bu deger zaman icinde her Full GC’den sonra yükselirdi.
Asagida Full GC’lerden sonra toplam heap kullanim alani yer aliyor:
275121K
275123K
272151K
272331K
268656K
270726K
267291K
267390K
Full GC’den sonra kullanilan heap alaninin kücüldügü görülmekte. Garbage Collector ölü nesnelerin hepsini cöpe atiyor. Uygulamanizda bu degeler göz önüne alindiginda memory leak olmadigi söylenebilir. Tabi uygulamayi uzun bir süre bu sekilde gözetlemek lazim.
Özet olarak JVM hesap alanini 6 GB’ye cikarmis olsada, uygulama bunun sadece 267MB’sini kullanmakta.
Sanirim 6GB uygulamaniz icin cok fazla. Uygulamaniz 1 ya da 1.5 GB ile yetinebilir.
Kenan
25 Haziran 2012Teşekkürler yanıtınız için…
Evet burada işin ilginç yanı bu heap alanının 6GB çıkması 15-20 sn içinde oluyor. Sistem 5 gün boyunca 3GB seviyelerinde stable çalışıyordu.
Tam da heap alanı 6GB seviyelerine geldiğinde :
Jun 20, 2012 1:23:50 PM org.apache.catalina.core.StandardWrapperValve invoke
SEVERE: Servlet.service() for servlet jsp threw exception
java.lang.OutOfMemoryError: PermGen space
at java.lang.ClassLoader.defineClass1(Native Method)
at java.lang.ClassLoader.defineClass(ClassLoader.java:621)
hatası vermiş saat 16:23:50 de sonra 16:24:08 da bir daha aynı hata,
daha sonra da ara ara
java.lang.OutOfMemoryError: PermGen space
loga yazılmış.
Size GC log dosyası gönderebilir miyim inceleme fırsatınız olur mu?
gcviewer-1.31-RC5 versiyonu açarsanız değişim grafikte çok net görünüyor.
Özcan Acar
25 Haziran 2012Dedigin gibi göndermis oldugunuz loglarda bir sorun yok. Eger OutoutMemoryError PermGen seklinde hata aliyorsaniz, o zaman permanent alani kücük. -XX:PermSize=… -XX:MaxPermSize= parametreleri ile büyütebilirsiniz. 86MB permanent alani icin kullaniyorsunuz, bunu 100 ya da 150MB ye cikarip, tekrar deneyebilirsiniz.
Kenan
25 Haziran 2012-XX:PermSize=128m ve XX:MaxPermSize=256m yaptık umarım sorun çözülür.
Değerli vaktiniz ve yorumlarınız için çok teşekkürler…
Pingback: Java’da Bilinmeyenler | Mert Bozkurt
Akın TRMN
17 Nisan 2015bir uygulama çalıştıracakken şu şekilde bir mesaj alıyorum.Daha önce bir sıkıntı yoktu simdi neden anlayamadım.ne yapmam gerekli şimdiden teşekkürler.
Exception in thread “AWT-EventQueue-2” java.lang.OutofmemoryError: Java Heap space
Bundan sonrada 20 satır daha bişiler yazıyor:)
Özcan Acar
17 Nisan 2015Uygulamaya daha fazla hafiza vermeniz gerekiyor.
Emre Emir
26 Kasım 2015Herkese Merhaba;
Aşağıdaki değerler bir uygulama sunucusundan, sunucuda 16gb ram ve 4 core( CPU E5-2660 v2 @ 2.20GHz) mevcuttur. Kullandığımız uygulma bir öğrenme yönetim sistemidir. SAKAI CLE
Sunucuda belli bir süreden sonra java cpu %100 olarak gösteriyor donmalar oluyor yanıt vermiyor. java cpu %100 olduğunda sunucun cpu su %100 olmuyor.
Konu hakkında yardımlarınızı bekliyorum.
export JAVA_OPTS=’-server -d64 -Xms14336m -Xmx14336m -XX:PermSize=256m -XX:MaxPermSize=512m -XX:NewSize=384m -XX:MaxNewSize=512m -Djava.awt.headless=true -XX:+UseParallelGC -Dhttp.agent=Sakai -Dorg.apache.jasper.compiler.Parser.STRICT_QUOTE_ESCAPING=false -Dsun.lang.ClassLoader.allowArraySyntax=true -verbose:gc -Xloggc:/opt/tomcat/logs/sakai_gc.log -XX:+PrintGCDetails -XX:+PrintGCTimeStamps -Duser.language=tr -Duser.region=TR’