web-gelistirme-sc.com

JBoss 7, Java.lang.OutOfMemoryError: PermGen alanı

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)?

25
MaVRoSCy

Bu, birden fazla yeniden dağıtımdan sonra gerçekleştiğinden, yaygın bir permgen sızıntısı olan bir classloader sızıntısı ile karşılaştınız.

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.

54
Craig Ringer

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.

8
Bohemian

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!

https://smalldata.tech/blog/2015/09/29/detecting-Java-permgen-memory-leak

4
Victor Parmar

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 
  • CMSPermGenSweepingEnabled ayarı bir Çöp toplama çalışmasında PermGen'i içerir. Varsayılan olarak, PermGen alanı hiçbir zaman Çöp toplama alanına dahil edilmez (ve bu nedenle sınırsız büyür).
  • CMSClassUnloadingEnabled ayarı, PermGen çöp Toplama taramasını, sınıf nesneleri üzerinde işlem yapmasını söyler. Varsayılan olarak, class Nesneleri, PermGen alanı kullanılıyorken bile bir istisna alır.

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. 

1
Kamal SABBAR