CPU kullanımının limitlerine uygun olduğu ve JBoss'un yeniden başlatılması gereken (
Java.lang.OutOfMemoryError: PermGen space) bu hatayı çarptım.
Daha eski JBoss sürümü için
MaxPermSize değerini artırmak için bir çözüm buldum. Sanırım aynı şey JBoss7 için de geçerli.
Bir problemle tekrar karşılaşmamak için hangi değer yeterince iyi olurdu? Bu sorundan kalıcı olarak kurtulmanın bir yolu var mı (örneğin farklı bir kullanalım VM JRockit gibi)?
Bu sevimli hayvanlar, konteynerin sahip olduğu nesnelerden uygulama sınıfı yükleyiciden yüklenen sınıfların örnekleri olan normal (zayıf olmayan) referanslar nedeniyle gerçekleşir. Bu referanslar dağıtımda temizlenmediyse, hala uygulamanın sınıf yükleyicisine güçlü bir referans zinciri vardır, bu nedenle GC'd olamaz ve yüklenen sınıflar serbest bırakılamaz.
Yaygın bir neden, eklenen uygulama sınıflarına statik olmayan referansları olan konteyner sınıflarındaki statik koleksiyonlardır.
JBoss AS 7, sınıf sistemindeki sızıntıları önlemek için modül sisteminde oldukça güçlü hükümler içeriyor; bu nedenle, birini tetiklemeyi başarmanıza şaşırdım. Glassfish'ten AS7'ye taşındığımdan beri bir sınıf yükleyici sızıntısı görmedim.
MaxPermSize'i artırmak size biraz zaman kazandırır, ancak sorundan kurtulmaz.
Sınıf yükleyicinin neden sızdırdığını araştırman gerekiyor. Bunu yapmak "eğlenceli". Vergilerden, aralıklı arızalardan ve duş temizliğinden hoşlanıyorsunuz, değil mi? Sızıntıyı izlemeye başlamanıza yardımcı olacak bazı bloglar için ilk pardaki bağlantılara bakın. Temel olarak, uygulama sınıf yükleyicinize başvurular için Dig için VisualVM ve OQL kullanmak ya da bir yığın dökümü alıp bulmak için
jhat (JDK’nin bir parçası) kullanmak isteyeceksiniz referanslar. Her iki durumda da, uygulama sınıflarından örnekler üzerinden uygulama sunucusundan sınıf yükleyicinize güçlü referans zincirinin nerede olduğunu bulmaktır.
Alternatif olarak, uygulamanızın bir kopyasını almaya yardımcı olabilir, ardından sızıntı bitene kadar bit parçalarını sökmeye başlayabilirsiniz. VisualVM veya diğer izlemeyi uygulama sunucusuna VM bağlayarak ve PermGen'in iki veya daha fazla konuşlandırma/yayılma döngüsünden sonra artış gösterip göstermediğini izleyerek sızıntı olup olmadığını anlayabilirsiniz. Dağıtma/dağıtma döngülerini otomatikleştirmeyi düşünün. Sızıntının nedenini uygulamanızın ve/veya bağımlılıklarınızın küçük bir kısmına kadar daraltın ve küçük, kendi kendine yeterli bir test durumu oluşturun, ardından bunu (a) JBoss AS 7 hakkında bir hata raporu olarak sunun; bunun olmasını engellemek ve (b) referansı tutan suçluyu durdurmak içindir.
Nedeni dağıtım arşivinizde bulunan bir bağımlılığa indirgerseniz, onu bir JBoss AS 7 modülüne taşımak sorununuzu çözebilir. Bunun için bir JBoss modülü oluşturun, AS7'nin
modules dizinine dağıtın ve konuşlandırmanıza
Manifest.MF'nuz veya bir
jboss-deployment-structure.xml aracılığıyla ekleyin. AS7 sınıfı yükleyicideki belgelere bakın .
Bu yüzden Proje Yapbozunun ertelenmesi beni üzüyor. Java needs bu sıkıntıdan kurtulan güçlü bir modül sistemi.
VM parametresi:
-XX:MaxPermSize=256M
Sadece sınırı aşmayacak kadar büyük yap.
Genel olarak konuşursak, perm gen belleği, Classes ve interned Strings ile ilişkili nesneler için kullanılır. Çok farklı sınıflar kullanmadıkça, bitmemelisin.
Aynı şeyi yapmak zorunda kaldık ve ne yazık ki visualvm bizim için fazla bir şey yapmadı.
Çökme sırasında ortaya çıkan yığın boşluğunu analiz etmek için Eclipse mat'ı kullandık ve daha sonra
ModuleClassLoader örneklerinin sızdırıldığını söyleyen
leak suspects raporunu inceledik.
Genel bakış sekmesindeki örneklerden birine tıklayıp ardından
merge shortest paths to GC roots +
exclude weak references seçerek bize bu
ModuleClassLoader örneklerinin GC'ed olmasına izin vermeyen suçluları verdi!
Neden olur
Java sanal makinesi bittiğinde, "PermGen" hatası oluşuyor. Kalıcı nesildeki hafıza. Java'nın bir hatırası olduğunu hatırlayın. dört kuşaklı nesil çöp toplayıcı: eden, genç, yaşlı ve kalıcı. Eden neslinde, nesneler çok kısa yaşadı ve çöp toplama Swift ve sık sık. Genç kuşak. Eden neslinden kurtulan nesnelerden oluşur (ya da gençten aşağı itilirdi. Çünkü eden neslin tam tahsisi sırasında doluydu), genç nesildeki çöp toplanması daha azdır. sık sık ama yine de oldukça düzenli aralıklarla olur (eğer uygulamanız aslında bir şeyler yapıp her şeyi. ve şimdi nesneler tahsis eder). Eski kuşak, bunu anladın. Bu içerir Genç nesilde hayatta kalan ya da itilmiş nesneler, Çöp toplama işlemi daha az görülmez ancak yine de olabilir. Ve nihayet, kalıcı nesil. Bu, sanal makine ebedi hayata destek vermeye karar verdi - ki bu. sorunun tam özü. Kalıcı kuşaktaki nesneler. hiçbir zaman çöp toplanmaz; yani, normal şartlar altında. jvm normal komut satırı parametreleriyle başlatılır. Ne olmuş yani web uygulamanızı yeniden konuşlandırdığınızda, WAR dosyanızın. açılır ve sınıf dosyaları jvm'ye yüklenir. Ve işte şey: neredeyse her zaman kalıcı kuşakta sona erer ... (alınan from: http://rlogiacco.blogspot.com/2009/02/jboss-and-permgen-outofmemoryerror.html )
İşte bazı tavsiyeler:
jVM'niz için bu parametreleri kullanın. Çöp Toplayıcıya, PermGen'de de algoritmasını çağırmasını söylerler.
set Java_OPTS=-Xms512m -Xmx1024m -XX:PermSize=512m -XX:MaxPermSize=1024m -XX:+UseConcMarkSweepGC -XX:+CMSPermGenSweepingEnabled -XX:+CMSClassUnloadingEnabled
JBOSS'nuzu yeniden başlatın, çünkü uygulamayı her dağıtdığınızda, PermGen'deki veri miktarını arttırırsınız.
Sun JVM yerine JRocket JVM'yi de kullanabilirsiniz. Çöp Toplayıcı algoritmasında PermGen bulunmuyor.