2012-09-10 24 views
8

Büyük bir denemenin bir parçası olarak bir kümede bir NetLogo (bir java simülasyon çerçevesi) simülasyonunu çalıştırmaya çalışıyorum. (Nispeten) basit bir simülasyonun görünüşte muazzam bellek gereksinimine şaşırdım. Küme üzerinde "java.lang.OutOfMemoryError: Java yığın alanı" "-Xmx2500M" boyutundan daha az bir şey için istisnalar atar. Tek bir yürütme, çalıştırılmak için 5 saat sürer. Aynı denemeyi hem Mac'lerimde (iMac ve MacBook Pro) çalıştırdım ve bir saatten daha kısa bir sürede, "-Xmx1024" ile hata yapmadan çalıştılar. Küme işlerinde "-XX: MaxPermSize = 250M" gerekir, ancak Mac'lerimde varsayılanın üzerinde bir artış gerekmez. Her durumda tam olarak aynı kavanozları kullanarak aynı kodu, aynı girdileri çalıştırdım.Aynı program, aynı JVM, ancak farklı makinelerde çok farklı bellek gereksinimleri ve yürütme süresi - neden?

64 bitlik JVMs her durumda kullanılan (ve bildiğim kadarıyla bunlar oldukça benzer biliyorum gibi):

<on the cluster> 
$ java -version 
java version "1.6.0_26" 
Java(TM) SE Runtime Environment (build 1.6.0_26-b03) 
Java HotSpot(TM) 64-Bit Server VM (build 20.1-b02, mixed mode) 

<on my macs> 
$ java -version 
java version "1.6.0_31" 
Java(TM) SE Runtime Environment (build 1.6.0_31-b04-415-10M3646) 
Java HotSpot(TM) 64-Bit Server VM (build 20.6-b01-415, mixed mode) 

Ve anahtarlama, başlangıçta küme üzerinde Sunucusu kullanıyordu (her durumda Müşteri JVM çalıştırıyorum müşteriye fark yaratmadı). Ben java 7, aynı büyük bellek ve yürütme zamanı sorunları ile küme üzerinde çalışmayı denedim.

Ben tamamen şaşırdım, bunu açıklayabileceğim kimse konuşamadım. Daha önce buralarda biri var mı? Herhangi bir yardım büyük takdir!

+0

Belki de -XX: + HeapDumpOnOutOfMemoryError ile bir yığın dökümü oluşturmalı ve sonra belleği ne kullandığını görmek için MAT veya benzerlerini kullanmalısınız. –

+0

VisualVM veya YourKit gibi bir ticari bellek uzmanı kullanacağım. –

+0

, bana iki farklı jvm sürümünüzün olduğu gibi görünüyor. Sorununuz olduğunu söylemiyorum ama katkıda bulunabilir. – Matt

cevap

3

Daha hızlı ağ veya disk IO olduğundan şüpheleniyorum. Bir diske yazmak için kuyruklar kullanıyorsanız veya bir bilgisayarın yetişebileceği ağa yazıyorsanız, ancak diğeri yapamıyorsa, sıra, makineyi yavaşlatıp sınırsız miktarda bellek kullanıyor olabilir.

daha hızlı ağı IO varsa elinden gelen ya daha hızlı veri göndermek (küçük sıraları tutulması) ya da veri çok hızlı

Bir çok bağlıdır (yani kuyruk tüketildiklerinden daha hızlı büyüyebilir) almak anlamına gelebilir yardım uygulamanızın gerçekte ne yaptığı. Programınız bir OOME aldığında, bir yığın dökümü alıp analiz etmenizi ve çok fazla bellek tüketen koleksiyonları (örneğin sıra) aramanızı öneririm.

+0

Çok hızlı cevap için teşekkürler. IO hızı ilk önerilerden biriydi. Küme çok daha yavaştır ve bu benim kendi makinelerimden çok daha yavaş başlatmayı açıklar. Ancak, program, bir kez çalıştırıldığında, diskin sonuna kadar (5 saat sonra) diske yazmıyor/yazmıyor ve bir satırı bir dosyaya yazıyor. Söylemeliyim ki, bu testler sırasında kümede herhangi bir şey yürüten başka kimse yok. Yığın çöplüğüne bakacağım, ama bu arada başka bir öneride bulunacak mıyım? – user1660640

+0

Bir kümeyi simüle ediyorsanız, geri döngüde bile olsa, herhangi bir ağ IO'nuz var mı? Hız verileri geri döngü üzerinden aktarılabilir ve işlemci ve işletim sistemi tarafından önemli ölçüde farklılık gösterebilir. –

+0

İşin tamamı (tek bir iş) tek bir küme düğümünde yürütülür: buradaki fikir birkaç yüz kadar işi aynı anda çalıştırmaktır. Gereken düğümler arasında iletişim yoktur, her iş kendi java süreci olarak tamamen kendi içinde yer alır. – user1660640

0

Sorun şu ki, Sunucu JVM'sini kullandığınızdan şüpheleniyorum. İstemci JVM, 64 bit makinelerde mevcut değildir. Istemci JVM için sorsa bile, size bir sunucu verecektir.