To'liq GC juda tez-tez bo'lib turadi

Bir tomcat misolida ishlaydigan Java veb-ilovasi bor. Yuqori vaqtlarda veb-ilovalar soniyada 30 sahifani tashkil etadi va odatda 15 atrofida.

Mening muhitim:

O/S: SUSE Linux Enterprise Server 10 (x86_64)
RAM: 16GB

server: Tomcat 6.0.20
JVM: Java HotSpot(TM) 64-Bit Server VM 1.6.0_14
JVM options:
CATALINA_OPTS="-Xms512m -Xmx1024m -XX:PermSize=128m -XX:MaxPermSize=256m
               -XX:+UseParallelGC
               -Djava.awt.headless=true
               -verbose:gc -XX:+PrintGCDetails -XX:+PrintGCTimeStamps"
JAVA_OPTS="-server"

Bir necha kunlik ish vaqti tugagandan so'ng Full GC tez-tez paydo bo'lib, dasturning mavjudligi uchun jiddiy muammo bo'lib qoladi. Tomcat qayta boshlanganidan keyin muammo yo'qoladi, lekin, albatta, 5-10 yoki 30 kundan so'ng (izchil emas) qaytib keladi.

The Full GC log before and after a restart is at http://pastebin.com/raw.php?i=4NtkNXmi

To'liq GC-ga 2,5 soniya kerak va har 6 sekundda sodir bo'lganligi sababli, ilovaning zarar ko'rgan 6.6 kunlik ish vaqtida qayta ishga tushirilishidan oldin jurnalni ko'rsatadi.

Keyinchalik, to'liq GC faqat 5-10 daqiqada sodir bo'lgan joyni qayta ishga tushirgandan so'ng, jurnalni ko'rsatadi.

To'liq GC'lar yuzaga kelganida (ular to'liq GC bilan ta'minlanganligiga ishonchim komil bo'lganda) jmap -dump: format = b, file = dump.hprof PID yoki 2 to'liq GClar orasida) va ularni http://www.eclipse.org/mat/ Lekin, kriminal gumonlarda foydali narsa olmadi:

  • 60MB: 1 "org.hibernate.impl.SessionFactoryImpl" misoli (ehcache bilan hozirda qo'llash)
  • 80MB: 1024 ta "org.apache.tomcat.util.threads.ThreadWithAttributes" misoli (tomcatning 1024 nafar ishchisi)
  • 45MB: 37 "net.sf.ehcache.store.compound.impl.MemoryOnlyStore" misoli (ular ehcachedagi mening ~ 37 ta keshim bo'lishi kerak)

Hech qachon OutOfMemoryError bo'lmayman.

Keyingi qarash kerak bo'lgan har qanday fikr?

11
Ko'plab yangi va olib tashlangan narsalar.
qo'shib qo'ydi muallif Thorbjørn Ravn Andersen, manba
to'plamga ko'proq narsalar bo'lgani uchun, ko'proq katta hajmdagi GC to'plami ko'proq vaqt talab qilishi mumkin, ammo ilovangizga ko'proq joy kerak bo'lsa, maksimal katak hajmining katta qiymatlari bilan tajriba qilish mumkin.
qo'shib qo'ydi muallif matt b, manba
qo'shib qo'ydi muallif matt b, manba
Agar serveringizda 16 gigabayt RAM mavjud bo'lsa, unda nega katta o'lchamli o'lchamdagi (-Xmx) katakchadan foydalanilmaysiz?
qo'shib qo'ydi muallif matt b, manba
"Men hech qachon OutOfMemoryError-ni topmadim" - emas, balki all xotira ishlatilgan, lekin butun GC mavjud bo'lib, eski avlod to'la. Ko'proq xotirani ajratish yosh genlardagi ob'ektlarni uzoqroq saqlashga imkon beradi - ko'proq kichik kollektsiyadan tozalanish ehtimoli ko'proq.
qo'shib qo'ydi muallif symcbean, manba
Sinov muhitida xatti-harakatlaringizni qayta yarata olasizmi? Ehtimol, ba'zi yuklarni sinash bilan. Men shunga o'xshash xatti-harakatni oldindan ayta olaman, lekin odatda ALOT yordamida profilerdan (bu serverni ishlab chiqarishda env ichida o'ldiradi).
qo'shib qo'ydi muallif pcalcao, manba
@symcbean: ma'nosini beradi. Uydagilarni ko'paytirmoqchiman va qayta baholayman.
qo'shib qo'ydi muallif cherouvim, manba
@matt b: Buni hal qildi. Iltimos, javob sifatida yozing, men qabul qilaman.
qo'shib qo'ydi muallif cherouvim, manba
@svaor: Men ko'rib chiqaylik. Ovoz foydali. rahmat!
qo'shib qo'ydi muallif cherouvim, manba
@matt b: Keyingi safar 2GB ni sinab ko'raman va nima bo'lishini bilib olaman.
qo'shib qo'ydi muallif cherouvim, manba
@pcalcao: Men buni o'tmishda qildim, lekin bu izchil emas. JMeter bilan to'la dudbo'yoqli stressni sinovdan o'tkazganimda, bu 6 kundan bir marta va 20 kundan keyin yana bir marta yuz berdi (!).
qo'shib qo'ydi muallif cherouvim, manba
Men hech qachon OutOfMemoryError dasturiga ega bo'lmagandim, shuning uchun dastur ishga tushirilgandan keyin u yaxshi. Bundan tashqari, men JVMga juda ko'p xotira berishni to'liq GCni sekinroq qilishini o'qidim. Bu haqiqatmi?
qo'shib qo'ydi muallif cherouvim, manba
Tutqinlik-mat bir JVM seansining ikki dumpsini taqqoslash mumkinligini eslayman. Bu sizga muammolar hali mavjud bo'lmagan holatlardagi farqni va tez-tez ko'rinadigan GClar bilan bog'liq vaziyatni ko'rsatishi mumkin.
qo'shib qo'ydi muallif svaor, manba

4 javoblar

Biz bu masalani hal qilsak, biz uni yosh avlodga nisbatan juda oz darajada kuzatdik. Garchi ko'plab qo'chqorlarni bergan bo'lsak-da, yosh avlodga bu haqli ulush berilmadi.

Bu shuni anglatadiki, kichik axlat to'plamlari tez-tez sodir bo'lardi va ba'zi yosh narsalar, shuningdek, katta axlat to'plamlari ma'nosini bildiradigan avlodga ko'chirilishiga olib keldi.

-XX: NewRatio -ni juda kam qiymat bilan (misol uchun 2 yoki 3) ishlatib ko'ring va bu yordamga murojaat qiling.

Qo'shimcha ma'lumotni bu erda topishingiz mumkin.

6
qo'shib qo'ydi

Men -Xmx1024m dan -Xmx2048m ga o'tishga muvaffaq bo'ldim va muammo yo'qoldi. Hozirda 100 kunlik ish vaqti bor.

4
qo'shib qo'ydi

Sizning holatingizda nima bo'lishi mumkin, sizda NewGen hayot aylanishiga qaraganda bir oz ko'proq vaqt davomida yashaydigan narsalar ko'p. Agar omon qolgan joy juda kichik bo'lsa, ular to'g'ridan-to'g'ri OldGenga boradi. -XX: + PrintTenuringDistribution ba'zi bir ma'lumotni berishi mumkin. YangiGeningiz etarli darajada katta, shuning uchun SurvivorRatio ni kamaytiring.

Shuningdek, jconsole ehtimol sizning xotirangiz bilan nima sodir bo'lishiga ko'proq ingl. tushuncha beradi, sinab ko'ring.

3
qo'shib qo'ydi

Bundan tashqari, JVM ning turli xil variantlarini sozlash bilan bir qatorda VMning yangi versiyasiga o'tishni taklif qilaman, chunki keyingi versiyalarda axlat kollektori (yangi eksperimental ishlamasdan ham) yaxshi sozlangan.

Bundan tashqari, agar JVMga qo'shimcha ram o'rnatilsa, GCni bajarish uchun zarur bo'lgan vaqtni oshirishi mumkin bo'lsa ham, butun 16 GB xotiradan foydalanish va xotira mashg'ulotini ko'paytirish o'rtasida savdo nuqtasi mavjud bo'lib, boshlamoq

XMS1024m -Xmx2048m -XX: PermSize = 256m -XX: MaxPermSize = 512m

Hurmat bilan

Massimo

2
qo'shib qo'ydi
OK, JVM ni ham yangilaydi. Rahmat.
qo'shib qo'ydi muallif cherouvim, manba
Ha, jurnallar taxminan ~ 64MB atrofida PSPermGenni namoyish etadi, bu taxminan jami sinfning kattaligi: JVM, tomcat, kutubxonalar va mening ilovam. To'g'ri?
qo'shib qo'ydi muallif cherouvim, manba
Harakat qilaman. Lekin 512 maxperm emasmi? Tomcat misolida faqat 40 ta qat'iy (tik turish) ob'ektlar va hech qanday bahor ramkalari mavjud bo'lmagan 1 ta dastur ishlaydi. Ushbu tomcatda faqat qayta ishlanishlar bo'lmaydi, faqat o'chirish/ishga tushirish.
qo'shib qo'ydi muallif cherouvim, manba
Ehtimol, taklif qilingan parametrlarim oddiygina taxmindir. JVMni yangilash uchun yaxshiroq narsa sifatida yangilashni xohlayman, shunga o'xshash muammolar bor edi (va boshqalar ham) va biz yangilash uchun Java yangilangan 27 ketdi. So'nggi yangilanish 29, lekin biz bilan ba'zi muammolar bor edi.
qo'shib qo'ydi muallif user1133275, manba