SORU
18 ŞUBAT 2009, ÇARŞAMBA


Java sanal Bellek Kullanımı Linux altında, çok fazla bellek kullanılır

Bir Java uygulaması Linux altında çalışan ile ilgili bir sorun var.

Ben bu uygulama, varsayılan yığın boyutu (64 MB) kullanarak başlattığınızda, üstleri sanal Hafıza 240 MB ayrılmış uygulamasını kullanarak uygulamaya görüyorum. Bu kaynak sınırlı görece olarak bilgisayar, başka bir yazılım ile bazı sorunlar yaratır.

Ayrılmış sanal bellek yığın sınıra ulaştığımızda bir OutOfMemoryError atılır çünkü her neyse, anladığım kadarıyla kullanılmayacaktır. Windows altında aynı uygulamayı araştırdım ve Sanal Bellek boyutu ve Yığın boyutu benzer olduğunu görüyorum.

Linux altında Java bir işlem için Sanal Bellek yapılandırmak ben zaten var mı?

Edit 1: sorun Yığını değildir. Sorun eğer 128, örneğin, hala bir Yığın kurdum linux değil gereken Sanal Bellek, 210 MB ayırır ki hiç.**

Edit 2: ulimit -v Kullanarak sanal bellek. miktarını sınırlayarak sağlar Eğer boyutu ayarlanabilir 204 MB altında ise, o zaman uygulama 204MB, 64 MB tek ihtiyacı yok olsa bile çalışmaz. Çok fazla sanal bellek gerektirir nedenini anlamak istiyorum. Bu değiştirilebilir mi?

Edit 3: birkaç diğer uygulamalar gömülü olan sistem, çalışan Var. Ve bu sistem sanal bellek sınırı var. (yorum, önemli bir ayrıntı)

CEVAP
18 ŞUBAT 2009, ÇARŞAMBA


Bu Java ile uzun soluklu bir şikayet oldu, ama büyük ölçüde anlamsız ve genellikle yanlış bilgiler bakıyor dayalı. Her zamanki lafzı "Merhaba Java alır 10 megabayt Dünya! gibi bir şey. Neden böyle bir şeye ihtiyacı var mı?" İşte 64-bit JVM bir iddia üzerinden 4 gigabyte ... en azından ölçüm formu ile almak için Merhaba Dünya yapmak için bir yol.

java -Xms1024m -Xmx4096m com.example.Hello

Farklı Şekillerde Hafıza Ölçmek için

Linux üzerinde, top komutu bellek için birkaç farklı sayılar verir. Merhaba Dünya örneği: hakkında ne diyor burada

  PID USER      PR  NI  VIRT  RES  SHR S %CPU %MEM    TIME   COMMAND
 2120 kgregory  20   0 4373m  15m 7152 S    0  0.2   0:00.10 java
  • VİRT sanal bellek alanı: sanal bellek haritası (aşağıya bakınız) her şeyin toplamı. Anlamsız, (aşağıya bakınız) ama artık değil.
  • RES ikamet set boyutu: şu anda RAM ikamet eden sayfa sayısı. Neredeyse her durumda, bu "çok büyük." diyerek zaman kullanmanız gereken tek sayıdır Ama özellikle Java ile ilgili konuşurken hala çok iyi bir sayı değil.
  • SHR diğer işlemler ile paylaşılan yerleşik bellek miktarıdır. Java bir işlem için, bu genellikle paylaşımlı kütüphaneler ve bellek eşlenen JARfiles sınırlıdır. Bu örnekte, sadece bir Java süreç çalışan vardı, 7k kitaplıkları işletim sistemi tarafından kullanılan bir sonucu olduğunu sanıyorum.
  • TAKAS varsayılan olarak açık değildir, ve burada gösterilen değil. Şu anda disk üzerinde ikamet eden, sanal bellek miktarını gösterirya aslında takas alanı olsun. İşletim sistemi çok iyi tutmak active sayfalarda RAM ve tek konu değiştirme (1) Daha fazla bellek satın almak, ya da (2) sayısını azaltın işler, o yüzden en iyisi görmezden bu sayı.

Windows Görev Yöneticisi için durum biraz daha karmaşıktır. Windows XP altında, "Bellek Kullanımı" ve "Sanal Bellek Boyutu" sütunları, ama official documentation anlamı konusunda bir şey söylemiyor. Windows Vista ve Windows 7 Daha fazla sütun ekleyin, ve aslında documented onlar. Bu," ölçümü çok yararlıdır; kabaca RES toplamı ve Linux üzerinde SHR karşılık gelir. "Çalışma Kümesi

Sanal Bellek, anlayış Göster

Sanal bellek bir proses tarafından tüketilen sürecinde bellek haritası olan her şeyin toplamıdır. Bu veri (Java yığın gibi), ama aynı zamanda paylaşılan kütüphaneler ve bellek eşlenen dosyaları program tarafından kullanılan içerir. Linux kullanabilirsiniz pmap komut görmek şeyler eşlenen içine alan işlem (şu andan itibaren ben sadece gidiyor bakın Linux, çünkü ne kullanıyorum; eminim vardır eşdeğer araçlar için (Windows). Burada "Merhaba" programı; tüm hafıza göster 100 satır uzunluğunda ve alışılmadık bin satırı bir liste var. Dünya hafıza göster bir alıntıdır.

0000000040000000     36K r-x--  /usr/local/java/jdk-1.6-x64/bin/java
0000000040108000      8K rwx--  /usr/local/java/jdk-1.6-x64/bin/java
0000000040eba000    676K rwx--    [ anon ]
00000006fae00000  21248K rwx--    [ anon ]
00000006fc2c0000  62720K rwx--    [ anon ]
0000000700000000 699072K rwx--    [ anon ]
000000072aab0000 2097152K rwx--    [ anon ]
00000007aaab0000 349504K rwx--    [ anon ]
00000007c0000000 1048576K rwx--    [ anon ]
...
00007fa1ed00d000   1652K r-xs-  /usr/local/java/jdk-1.6-x64/jre/lib/rt.jar
...
00007fa1ed1d3000   1024K rwx--    [ anon ]
00007fa1ed2d3000      4K -----    [ anon ]
00007fa1ed2d4000   1024K rwx--    [ anon ]
00007fa1ed3d4000      4K -----    [ anon ]
...
00007fa1f20d3000    164K r-x--  /usr/local/java/jdk-1.6-x64/jre/lib/amd64/libjava.so
00007fa1f20fc000   1020K -----  /usr/local/java/jdk-1.6-x64/jre/lib/amd64/libjava.so
00007fa1f21fb000     28K rwx--  /usr/local/java/jdk-1.6-x64/jre/lib/amd64/libjava.so
...
00007fa1f34aa000   1576K r-x--  /lib/x86_64-linux-gnu/libc-2.13.so
00007fa1f3634000   2044K -----  /lib/x86_64-linux-gnu/libc-2.13.so
00007fa1f3833000     16K r-x--  /lib/x86_64-linux-gnu/libc-2.13.so
00007fa1f3837000      4K rwx--  /lib/x86_64-linux-gnu/libc-2.13.so
...

Formatı hızlı açıklama: parçanın sanal bellek adresi her satırda başlar. Bu kesim boyutu, izinleri ve kesim kaynak tarafından takip edilir. Bu son madde ya da bir dosya ya da "bellek bloğu mmap ile ayrılan gösterir.", anon

Üstten başlayarak, var

  • JVM yükleyici (yani, java yazdığınızda idare ediliyor programı). Bu çok küçük; yaptığı tüm gerçek JVM kodu depolandığı paylaşılan kitaplıkları yükleyin.
  • Anon blok Java yığın ve iç veri tutan bir grup. Bu Sun JVM, öbek her biri kendi bellek bloğu birden fazla nesiller, ayrılır. JVM sanal bellek alanı -Xmx değerine göre ayırır; bu bitişik bir yığın izin verir unutmayın. -Xms değeri DAHİLİ olarak "program başlıyor" ve bu sınıra yaklaştı gibi. çöp toplama tetiklemek için kullanıldığını söylerdi.
  • Bellek eşlenen JARfile, bu durumda tutan dosya "sınıfları ile İLGİLENİYORUZ." -Göster hafıza KAVANOZ, çok verimli (karşı başından beri her zaman okuma) içindeki dosyaları erişebilirsiniz. Sun JVM sınıf, bellek-harita tüm Kavanozları; uygulama kodunuzu bir KAVANOZ erişmek için gerekiyorsa, aynı zamanda bellek haritası.
  • Başına iş parçacığı iki iş parçacığı için veri. 1M blok bir iş parçacığı yığın; 4K bloğuna gider bilmiyorum. Gerçek bir uygulama için, onlarca değilse bu girdileri bellek haritası ile tekrarlanan yüzlerce göreceksiniz.
  • Gerçek JVM kodu tutan paylaşılan kitaplıkları. Bu birkaç vardır.
  • C standart kütüphane için paylaşılan kitaplık. Bu kesinlikle Java parçası olmayan JVM yükleyen pek çok şeyden sadece biri.

Paylaşılan kitaplıklar özellikle ilginç: her bir paylaşılan kütüphane bulunmaktadır en az iki kesimi: salt okunur bir kesimi içeren kütüphane Kodu ve okuma-yazma segment içeren genel işlem başına veri Kütüphanesi (bilmiyorum kesimi ile izinleri yok; ben sadece gördüm üzerinde x 64 Linux). Kütüphane salt okunur bölümü Kitaplığı kullanan tüm süreçler arasında paylaşılan olabilir; örneğin, libc sanal bellek alanı 1.5 M olan paylaşılabilir.

Sanal Bellek Boyutu Önemli mi?

Sanal bellek harita, bir sürü içerir. Bazıları salt okunur, bazıları paylaşılır, ama asla (bu örnekte yığın 4Gb neredeyse tüm eg) tahsis dokundu. Ama işletim sistemi ihtiyacı olan şey sadece yük kadar akıllıdır, sanal bellek boyutunu büyük ölçüde ilgisizdir.

Sanal boyut önemli ise sadece 2 GB (veya, bazı durumlarda, 3 Gb) Adres ayıramıyor 32-bit işletim sistemi üzerinde çalışıyor. Bu durumda kıt kaynak ile uğraştığını ve bileşimleri, bellek haritası için yığın boyutunu azaltmak gibi büyük bir dosya yapmak ya da çok fazla iş parçacığı oluşturmak için olabilir.

Ancak, 64-bit makineler her yerde göz önüne alındığında, Sanal Bellek Boyutunu tamamen alakasız bir istatistik önce çok uzun süreceğini sanmıyorum.

İkameti Boyutu Önemli Ayarlanır?

Resident Set boyutu aslında RAM sanal bellek alanı bölümüdür. Eğer RSS toplam fiziksel bellek önemli bir kısmını oluşturuyor büyürse, endişe başlatmak için zaman olabilir. RSS tüm fiziksel bellek büyür ve sistemi değiştirmeyi başlarsa, endişelenmek için zaman geçiyor.

Ama RSS de yanıltıcı, özellikle hafif yüklü bir makinede. İşletim sistemi sayfalarda bir süreç olarak kullanılan geri ödemelerine için çaba sarf etmiyor. Böyle yaparak elde edilecek çok az faydası vardır, ve bu süreç eğer pahalı sayfa hatasına potansiyeli gelecekte sayfası dokunur. Sonuç olarak, RSS istatistik aktif kullanımda olmayan bir sürü sayfa içerebilir.

Alt Satırda

Takas değilsen, çeşitli hafıza istatistikleri, sana ne söylediğini aşırı endişe etme. İhtar ile büyüyen bir RSS bellek sızıntısı bir tür gösterebilir.

Java programı ile, yığın içinde neler olduğuna dikkat etmek çok daha önemlidir. Alan toplam miktarı tüketilen önemli olduğunu ve bunu azaltmak için atabileceğiniz bazı adımlar vardır. Daha önemli olan çöp toplama harcamak ve öbek toplanan parçalar elde olan zaman miktarı.

Diski (yani veritabanı) erişim pahalıdır, ve hafıza daha. Eğer başka bir işlem yapabilirsiniz.

Bunu Paylaş:
  • Google+
  • E-Posta
Etiketler:

YORUMLAR

SPONSOR VİDEO

Rastgele Yazarlar

  • BetterCoder

    BetterCoder

    17 Aralık 2012
  • K-391

    K-391

    23 EKİM 2012
  • rekjavicxxx

    rekjavicxxx

    28 EKİM 2007