2011-12-13 18 views
12

Ölmekte olan bir uygulamadan yaptığım bir bellek dökümü var. Bütün mevcut yığınları tüketmiştir (-Xmx1024m). Web sayfalarını taramak için com.gargoylesoftware.htmlunit.WebClient kullanır. Dakikada birkaç http isteği yapar, birkaç gün içinde ölür. Çöp kutusundan görüldüğü gibi, her biri taranan bir sayfanın tam içeriği de dahil olmak üzere, ilgili nesnelerin tonlarıyla birlikte, her biri 17123 örneğiyle HtmlPage sınıfına sahiptir.Avcılık bellek sızıntıları, VisualVM: "GC kökü bulunamadı". Sıradaki ne?

Neden HtmlPage'un çöp toplandığını anlamıyorum. Örnek referansları araştırdım ve herhangi bir kodumu referans olarak görmüyorum ve VisualVM, "GC root bulunamadı" diyor. Anladığım kadarıyla, nesnenin gc için uygun olduğu, ancak işe yaramadığı anlamına gelmelidir.

Uygulama basit bir bağımsız işlem olarak çalışıyor, herhangi bir web kapsayıcı veya uygulama sunucusu kullanmıyor.

Herhangi bir ipucu? Başka neye bakmalıyım?

Özellikleri:

  • HtmlUnit'in v2.7
  • java versiyonu "1.6.0_13" Java (TM) SE Runtime Environment (build 1.6.0_13-b03) Java HotSpot (TM) Sunucu VM (Linux my.lan
  • 11.3-B02, karışık mod) inşa 2.6.18-128.el5 1. SMP Çar 17 Aralık 11:42:39 EST 2008 i686 i686 i386 GNU/Linux

Update1

Ben YourKit Java Profiler tarafından dökümü analiz etmeye çalıştık. 310mb tutulan boyuta sahip bir çok java.lang.ref.Finalizer nesnesini gösteriyor. Onlar net.sourceforge.htmlunit.corejs.javascript.NativeGenerator#finalize() finalizer için oluşturulmuş ve NativeGeneratorWindow, daha sonra HtmlPage ve her şey için ifade eder.

Herkes neden bellekte kaldığını biliyor mu?

Not: Meraklı ancak VisualVM, "bekleyen sonlandırmayı" sıfır olarak gösterdi.

+0

JVM için belirli komut satırı argümanlarını kullandınız mı? –

+0

@ThomasJungblut '-Xmx1024m -XX: MaxPermSize = 128m -XX: + PrintGCDetails -XX: + PrintGCTimeStamps -XX: + UseConcMarkSweepGC' – kan

+0

Ayrıca htmlunit 2.8 ile bir bellek sızıntısı yaşıyorum. Bir geçici çözüm olarak, WebClient'i günde bir kez yeniden örneklendiririm. Umarım bu hatayı izleyebilirsin. – milan

cevap

1

sayfa (lar) ile bitirdiniz sonra webClient.closeAllWindows() çağırarak emin olun - Aksi JavaScript parçacığı bir nesne olmayan olduğunda vs. sayfası kaynakları

+1

I 'setJavaScriptEnabled adres (yanlış) '. Küçük bir test yapmak için çalıştı ve "closeAllWindows" olmadan bile iyi çalışıyor gibi görünüyor. Ama denemeye devam ediyorum ... – kan

+0

XmlUnit ile taramanın sadece sebebinin sayfalarda JavaScript kullanabileceğini düşünürdüm. Oh iyi;) – maximdim

+0

Diğer bazı sayfalarda (farklı işlemlerde gezinme) javascript kullanılır, ancak bu özel uygulamaya ihtiyaç yoktur, ancak daha sık tarar. – kan

1

için tutma başvurular çalıştırmak devam ediyor JVM, nesnenin bir örneğini oluştururken oluşturulan nihai nesne() yöntemini oluştururken, oluşturulan nesneye başvuruda bulunan java.lang.ref.Finalizer öğesini oluştururken, finalize() yöntemi tamamlanmadan önce toplanan çöpleri almaz. Bellek sızıntısı, java.lang.ref.Finalizer-lerden zamanında temizlenememektedir. Bu sonlandırıcıların temizlenmesi, daha düşük önceliğe sahip ayrı bir sonizer daemon iş parçacığı tarafından yapılır; bu nedenle, uygulanan finalize() yöntemiyle çok sayıda nesne oluşturursanız, bellek tükendiğinizde.

Onun tüm çok iyi tarif:

http://www.fasterj.com/articles/finalizer2.shtml

Bu da bir çözüm olarak önermek şudur:

Finalizer 'cin parçacığı "belirgin bir yolu önceliğini arttırmaktır' - Bunun için bir API yoktur, bu yüzden ismiyle bulmak için tüm thread'ları çalıştırmanız ve ardından önceliğini artırmanız gerekir. "

İyi şanslar