MATdan foydalanib, HeapDump tahlili

MATdan foydalanib, HeapDump tahlili

Ishlashni tahlil qilishning klassik usuli, Heap Dump

K8s muhitida loyiha ustida ishlayotganimda, ma'lum bir podning takroran qayta ishga tushayotganini aniqladim. Pod nima uchun qayta ishga tushayotganini bilish uchun Last State xususiyatini ko'rib chiqish natijasida, sabab aniq OOM edi. Odatda, podlar bunday cheksiz qayta ishga tushayotganda, aksariyat hollarda OOM Killed asosiy sabab bo'ladi.

Bunday vaziyatda OOMni keltirib chiqaruvchi sababni topish uchun, avval Logni tekshiramiz. Biroq, bunday Logni tekshirganda OOM sababini oson topish mumkin emas. Chunki OOMning asosiy sababi xato emas, balki ip torayishi, ya'ni DB I/O juda uzoq davom etayotganligi sababli asinxron protsess jarayonida ishlashni toraytirishi hisoblanadi. Xatoliklar logsiz, xotira asta-sekin to'lib borib, pod o'lish holatida, faqat loglar orqali sababni aniqlash qiyinlashadi.

Agar Log orqali OOMning sababini tahlil qilish qiyin bo'lsa, Heap Dump juda foydali yordam bera oladi. Bu eng an'anaviy jarayon tahlili usuli bo'lib, hozirgi kunga qadar backend ish faoliyatini tahlil qilishda eng ko'p foydalaniladigan texnologiyalardan biridir. Heap Dump ma'lum bir vaqtda JVM xotirasida mavjud bo'lgan barcha ob'ektlar va ularning havola munosabatlarini suratga olib, qaysi ob'ekt xotirani egallab turganini va nima uchun qaytarilmayotganini statik ko'rinishda ko'rishini ta'minlaydi.

Biroq, to'g'ridan-to'g'ri toza Heap Dumpni tahlil qilish uchun faylning o'zi foydalanuvchi uchun qulay emas, o'qilishi qiyin muammo bor. O'n minglab ob'ektlar va havolalar binar holatda bir-biriga bog'lanib qolgan asl faylni inson tomonidan to'g'ri talqin qilish deyarli imkonsizdir. Bunday vaziyatda foydali foydalanuvchi Memory Analyzer Tool (MAT) deb ataladigan ochiq manba tahlil vositasi bo'ladi.

Shunday qilib, OOM nima

MATni chuqurroq ko'rib chiqishdan oldin, biz duch kelgan OOM (Out Of Memory) holati aniq qanday hodisa ekanligini aniqlashimiz kerak. OOM, aslida, ilova foydalana oladigan xotira tugashi va yangi ob'ektlar uchun joy ajratish imkoniyati yo'qolishi holatini ifodalaydi. Xuddi shunday xotira yetishmovchiligi bo'lsa ham, bu holat ikki katta qatlamda yuzaga keladi va ularni farqlash muammoni hal qilishning birinchi qadamidir.

image1.png

* Rasm manbasi: https://www.cnblogs.com/java1024/p/12381457.html

Birinchisi Java Virtual Machine (JVM) ichida yuzaga keladigan OutOfMemoryError'dir. JVM ishga tushganda xotira (Heap) maksimal hajmini belgilaydi va o'sha chegarada ob'ektlarni jalb qiladi, lekin qaytarilmagan ob'ektlar yig'ilib qolsa, xotira chegaraga yetgach, JVM java.lang.OutOfMemoryError'ni jo'natadi va normal ish faoliyatini to'xtatadi.

image2.jpeg

* Rasm manbasi: https://suneeta-mall.github.io/blog/2021/03/14/wth-who-killed-my-pod---whodunit/

Ikkinchisi konteyner darajasida yuzaga keladigan OOM Killed. K8s muhitida podlar xotira cheklovi bilan taqsimlanadi, agar konteyner foydalanayotgan haqiqiy xotira bu chegardan oshib ketadigan bo'lsa, mezbon OOM Killer ushbu jarayonni majburan to'xtatadi. Bu paytda pod oxirgi holatda OOMKilled kodini qoldirib, 137 (128 + SIGKILL 9) chiqish kodiga ega bo'ladi va qayta ishga tushirish siyosatiga muvofiq takroran ishga tushadi.

Muammoni murakkablashtiradigan narsa, OOM ko'pincha ma'lum bir daqiqada sodir bo'lmaydi, balki sekin rivojlanayotgan to'planish natijasi hisoblanadi. Kutilmagan ob'ektlarni asta-sekin xotiraga to'planadi va Garbage Collector qaytarishni qayta sinab ko'radi, biroq hamon bir joydan kuchli ravishda havola qilinganligi sababli qiyinchilik bo'ladi. Qaytarilmagan ob'ekt chegaradan oshib ketganda OOM kelib chiqadi, shuning uchun haqiqiy xato sodir bo'lgan vaqt logida oxirgi marta xotira so'ragan, lekin muvaffaqiyatsizlikka uchragan aybsiz kod ko'rsatilishi ko'p hollarda uchraydi. Oqibatda, OOMning haqiqiy sababini aniqlash uchun xato sodir bo'lgan paytda emas, balki o'shidan avvalgi vaqt davomida xotirada nima va qanday qo'shilganligini ko'rib chiqishimiz kerak. Aynan shu nuqtada Heap Dump va uni tahlil qiluvchi MATga ehtiyoj yuzaga keladi.

Memory Analyzer Tool

Memory Analyzer Tool (keyingi o'rinlarda MAT) Eclipse fondi tomonidan taqdim etilgan ochiq manba Heap Dump tahlil vositasidir. Inson o'qishi qiyin bo'lgan xom Heap Dump (.hprof) faylini parsel qilish orqali, qaysi ob'ekt qancha ko'p xotirani egallab olganini va o'sha ob'ektni nima uchun GC maqsadiga olmasligini vizual tarzda namoyish etadi.

MATning asosiy nuqtasi Shallow Heap va Retained Heap deb ataladigan ikkita ko'rsatgichdir. Shallow Heap ob'ektning o'zi egallab turgan xotira hajmini, Retained Heap esa ushbu ob'ekt GC bo'lsa, qaytariladigan xotira umumiy hajmini anglatadi. OOM sababini aniqlashda Retained Heap'ni anormallik sifatida juda katta ob'ektlarni kuzatish juda muhimdir. Bitta ob'ekt egallab turgan hajmidan ko'ra, o'sha ob'ektni quchoqlab turuvchilar xotira umumiy raqami haqiqiy suyuqlik o'lchovini bildiradi.

image3.png

* Rasm manbasi: AnyLogic Help, “Memory analyzer”, https://anylogic.help/advanced/debug/memory-analyzer.html

Ushbu View Heap Dump faylini MAT (Memory Analyzer Tool) ga import qilganda ko'rish mumkin. Memory Analyzer Toolning asosiy funktsiyasini ta'minlovchi View bo'lib, MAT Heap Dumpni ko'rib, xotira oqishi deb taxmin qilinayotgan nuqtalarni ko'rsatadi. Doira shaklidagi grafik orqali Jarayonning Heapda egallayotgan ulushini ko'rsatadi va qaysi ma'lumotlar Heapni ortiqcha egallayotganini aniqlash mumkin.

image4.png

* Rasm manbasi: AnyLogic Help, “Memory analyzer”, https://anylogic.help/advanced/debug/memory-analyzer.html

Shuningdek, quyidagi ekranlarni ham ko'rish mumkin.

Ushbu ekran MAT Heap Dumpni tahlil qilgandan so'ng avtomatik tarzda yaratilgan Leak Suspects hisobotidir. MAT faqatgina ob'ektlar ro'yxatini sanab chiqish bilan cheklanmay, noan'anaviy darajada ko'p xotira egallayotgan ob'ektlarni “oqish shubhasi nuqtasi (Leak Suspect)” deb ko'rsatadi. Ekranning yuqorisidagi doira grafiki butun Heapda har bir shubhali ob'ektning ulushini vizual tarzda aks ettiradi, agar bitta ob'ekt yoki ma'lum bir klassning nusxalari aksariyatni egallasa, o'sha hudud katta ulushda ta'kidlanadi.

Grafikning pastki qismida har bir shubha nuqtasi haqida qisqacha izohlar ham taqdim etiladi. Qanday klass qayta ishlash Heapini qanchalik egallayotganini va o'sha ob'ekt qanday ClassLoader yoki havola yo'li orqali qo'llab-quvvatlanayotganini tabiiy tilga yaqin shaklda tartibga soladi, shu sababli Heap Dump tahliliga o'rganmagan dasturchilar ham oqish sabablarini tezda qisqartira oladi. Jiddiy Dominator Tree tahliliga kirishdan avval, eng birinchi ko'rishi va tahlil yo'nalishini belgilash uchun foydali ekan.

Heap Dumpni chiqarish usuli

Heap Dump avtomatik ravishda OOM o'zgarishi yuz beradigan momentda yaratilishiga sozlanishi yoki ishga tushirilayotgan jarayonga bevosita buyruq berish orqali chiqarilishi mumkin. Operatsion muhitda OOM yuz beradigan paytdagi holatni qayd etish eng muhimdir, shuning uchun JVM variantlari orqali avtomatik dump sozlamalari samarali.

-XX:+HeapDumpOnOutOfMemoryError opsiyasini qo'shsangiz, OutOfMemoryError yuz beradigan paytda avtomatik ravishda .hprof fayli yaratiladi va -XX:HeapDumpPath bilan saqlash yo'lini belgilashingiz mumkin. Jarayonda darhol chiqarish zarur bo'lsa, jmap -dump:live,format=b,file=heap.hprof <pid> buyrug'ini ishlatish mumkin. live opsiyasini berishda dumpdan oldin Full GC bir marotaba bajaringan, faqatgina hayotda qolgan ob'ektlar tahlil qilinadi.

Biroq K8s muhitida bir narsa hisobga olinishi kerak. Pod OOM sababli o'ldiriladigan paytda konteyner tugaganida ichida yaratilgan dump fayllari ham yo'qolib ketishi mumkin. Shuning uchun HeapDumpPathni PersistentVolume kabi doimiy saqlash yo'llariga belgilash yoki alohida deyilgan konteyner orqali tugashidan oldin fayl tizimiga kirish usuli birgalikda ko'rib chiqilishi kerak.

Dominator Tree yordamida oqish ob'ektlarini izlash

Xotira sarf-xarajatlari doimiy ravishda oshib boradigan muammolar holatida chiqarilgan Heap Dump MAT Dominator Tree orqali ochilganida, ma'lum bir klassning nusxalari noan'anaviy darajada ko'p Retained Heapni egallayotganligini aniqladik. Dominator Tree ob'ektlar orasidagi hibs olish munosabatlarini daraxt shaklida ko'rsatib, qaysi ob'ekt boshqa ob'ektlarning xotirasini qanday qilib ushlab turishini bir qarashda tushunishga imkon beradi.

Aslida ma'lum darajada yig'ilishi kerak bo'lgan ob'ektlar nega doimo to'planayotganini tekshirish uchun Path to GC Roots funksiyasidan foydalandik. Bu ulangan ob'ektning GC Rootdan qaysi havola yo'li orqali ulanishini orqaga tushirish funksiyasidir, kim ob'ektni ushlab turib, qo'yib yubormayotganligini aniq ko'rsatadi. Tahlil natijalari, ishlash tezligidan o'tib ketayotgan xabar ob'ektlari to'plovchiga doimo yuklanayotganini va lekin iste'mol qilinmasdan, kuchli havola bilan qoldirilganligini ko'rsatdi, shuning uchun Garbage Collector xotirani qayta olmayapti.

Natijada asinxron ishlov berish jarayonida DB I/O torikligi olib kelib, xabar iste'moli tezligi ishlab chiqarish tezligini kuzatib bo'lmaydi va qayta ishlanmagan ob'ektlar heapga cheksiz yuklanib OOMga olib keldi. Yaxshiyamki, ushbu holatni Heap Dump tahlil jarayonida aniqlash mumkin bo'ldi, va biznes mantig'ida DB I/Oni yaxshilash orqali ishlash tezligini qisqartirib ob'ektning cheksiz to'planish holatini oldini olishimiz mumkin edi.

Xulosa qilib

Heap Dump "allaqachon sodir bo'lgan OOMning kimligini" eng aniq ko'rsatuvchi vositadir. Loglardan ko'rinmaydigan va haqiqiy vaqt ko'rsatkichlari bilan sababini aniqlash qiyin bo'lgan xotira oqimi muammosi bilan yuzma-yuz kelganda, o'sha paytdagi yerni to'liq o'rganib, obyekt havolalarining tugunini yechish uchun klassik tahlil usuli sifatida o'ylashingiz mumkin. Eng asosiysi, Heap Dump tahlili faqatgina joriy muammoni hal qilish bilan cheklanmay, obyektning qanday umr tsikli davomida yaratilishi va yo'q bo'lishi, shuningdek, qanday havola munosabatlari xotira qaytarilishini to'sishini chuqur tushunishga imkon beradi. Bunday tahlil tajribasi bir marta to'planganida, keyinchalik shunga o'xshash alomatlarni tezroq aniqlashga va hatto sochilmalar sodir bo'lmaydigan tuzilmani loyihalash ko'nikmasiga olib kelishi bilan uning qiymati katta deb o'ylayman.

jungboke

Site footer