Windows XP'de maksimum Java belleği


103

32 bit Windows XP (Java 1.4, 1.5 ve 1.6) üzerinde çalışan Java SE için her zaman 1400 megabayt ayırabildim.

java -Xmx1400m ...

Bugün aynı seçeneği Java 1.5_16 ve 1.6.0_07 kullanan yeni bir Windows XP makinesinde denedim ve şu hatayı aldım:

Error occurred during initialization of VM
Could not reserve enough space for object heap
Could not create the Java virtual machine.

Deneme yanılma yoluyla, bu makineye ayırabildiğim en fazla 1200 megabayt gibi görünüyor.

Bir makinenin neden 1400'e ve diğerine sadece 1200'e izin verdiğine dair bir fikriniz var mı?

Düzenleme: Makine, Windows'un tanıyabileceği yaklaşık 3,5 GB'lık 4 GB RAM'e sahiptir.


64 bit WindowsXP sistemleri nadir olsa da, en azından benim deneyimlerime göre, uygulamayı 32 bitlik bir kabukta veya 64 bitlik bir kabukta çalıştırmak arasındaki maksimum farkı fark edeceksiniz.
djangofan

Yanıtlar:


124

Windows'un sanal bellek yönetimine sahip olduğunu ve JVM'nin yalnızca adres alanında bitişik olan belleğe ihtiyacı olduğunu unutmayın . Bu nedenle, sistemde çalışan diğer programlar, yığın boyutunuzu mutlaka etkilememelidir. Yolunuza çıkan şey, adres alanınıza yüklenen DLL'lerdir. Ne yazık ki, Windows'daki bağlantı sırasında DLL'lerin yeniden konumlandırılmasını en aza indiren optimizasyonlar, parçalanmış bir adres alanına sahip olma olasılığınızı artırır. Her zamanki şeylerin yanı sıra adres alanınızı kesmesi muhtemel şeyler arasında güvenlik yazılımı, CBT yazılımı, casus yazılım ve diğer kötü amaçlı yazılım türleri bulunur. Farklılıkların olası nedenleri, farklı güvenlik yamaları, C çalışma zamanı sürümleri, vs.'dir. Aygıt sürücülerinin ve diğer çekirdek bitlerinin kendi adres alanları vardır (4GB 32-bit alanın diğer 2GB'si).

Sen olabilir daha kompakt adres alanına da DLL rebase çalışırken adresinden JVM süreci ve görünüm içinde DLL bağlamaları geçiyor deneyin. Eğlenceli değil, ama çaresizsen ...

Alternatif olarak, 64 bit Windows'a ve 64 bit JVM'ye geçebilirsiniz. Başkalarının önerdiklerine rağmen, daha fazla RAM çiğneyecek olsa da, çok daha fazla bitişik sanal adres alanına sahip olacaksınız ve bitişik olarak 2 GB tahsis etmek önemsiz olacaktır.


5
Bellek dll'lerinin nereye yüklendiğini görmek için İşlem Gezgini'ni kullanın. Genellikle güncellenmiş bir sürücü, adres alanınızın ortasına yapışır. REBASE komutunu kullanarak bunları kolayca yoldan çekebilirsiniz. Unutmayın, dll yeniden güncellenebilir ve bazı şeyleri bozabilir.
brianegge

2
Bunu hiçbir zaman bir cevap olarak kabul etmedim ve yine de stackoverflow yanıt olarak işaretledi.
Steve Kuo

@Christopher, 32 bit Windows XP'de 64 bit JVM kullanmak mümkün mü?
Pacerier

@Pacerier Üzgünüm, sorgunuzu kaçırdım. AFAIK, bu mümkün değil. OS X'in 32-bit çekirdekli 64-bit kullanıcı alanı için bazı hileleri vardı, ancak Windows için böyle bir şey duymadım.
Christopher Smith

@ChristopherSmith, Btw, " Sistemde çalışan diğer programların yığın boyutunuzu etkilememesi gerektiğini " söylediniz . Öyleyse, bu sonucu nasıl açıklarız: stackoverflow.com/questions/9303889/… ?
Pacerier

50

Bunun bitişik hafıza ile ilgisi vardır.

İşte bunu daha önce soran biri için, sözde bir " sanal makine tanrısından" çevrimiçi olarak bulduğum bazı bilgiler :

Yığın için bitişik bir bellek bölgesine ihtiyaç duymamızın nedeni, yığının başlangıcından itibaren (ölçeklenmiş) uzaklıklar tarafından indekslenen bir dizi yan veri yapısına sahip olmamızdır. Örneğin, her 512 baytlık yığın için bir bayta sahip olan bir "kart işareti dizisi" ile nesne referans güncellemelerini izliyoruz. Yığın içinde bir referans depoladığımızda, kart işareti dizisindeki ilgili baytı işaretlememiz gerekir. Mağazanın hedef adresini sağa kaydırıyoruz ve bunu kart işareti dizisini indekslemek için kullanıyoruz. Java'da yapamayacağınız eğlenceli adresleme aritmetik oyunları (C ++ 'da :-) oynamak zorunda.

Genellikle mütevazı bitişik bölgeler elde etmekte sorun yaşamıyoruz (Windohs'ta yaklaşık 1,5 GB'a kadar, Solaris'te yaklaşık 3,8 GB'a kadar. YMMV.). Windohs'ta sorun çoğunlukla JVM başlamadan önce yüklenen ve adres alanını bölen bazı kitaplıkların olmasıdır. / 3GB anahtarını kullanmak bu kitaplıkları yeniden başlatmaz, bu nedenle bunlar bizim için hala bir sorun.

Yığın yığınlarını nasıl yapacağımızı biliyoruz, ancak bunları kullanmanın bazı ek yükleri olacaktır. Daha hızlı depolama yönetimi için 32 bit JVM'de daha büyük yığınlar için yaptığımızdan daha fazla talebimiz var. Gerçekten büyük yığınlar istiyorsanız, 64 bit JVM'ye geçin. Hala bitişik belleğe ihtiyacımız var, ancak 64 bit adres alanına girmek çok daha kolay.


Bu çok ilginç. Her zaman neden 1500 MB olduğunu kendime sordum, şimdi anladım, teşekkürler!
Tim Büthe

3
Asırlık bir soruyu takip ettiğim için özür dilerim, ancak bu şimdiye kadar gördüğüm en iyi cevap. Ancak JVM, maksimum yığın boyutunu alamıyorsa neden başlangıçta başarısız oluyor ? Minimumun üzerindeki en iyi boyuta sessizce razı olması gerekmez mi?
Stroboskop

19

Windows için Java yığın boyutu sınırları şunlardır:

  • 32 bit Java'da olası maksimum yığın boyutu: 1,8 GB
  • 32 bit Java'da önerilen yığın boyutu sınırı: 1,5 GB (veya / 3 GB seçeneğiyle 1,8 GB )

Bu, daha büyük bir Java yığını elde etmenize yardımcı olmaz, ancak artık bu değerlerin ötesine geçemeyeceğinizi biliyorsunuz.


10

Bitişik olmayan bir yığını işleyebilen Oracle JRockit , / 3GB anahtarıyla Windows 2003 / XP'de 2.85 GB Java yığın boyutuna sahip olabilir. Görünüşe göre parçalanma, bir Java yığınının ne kadar büyük olabileceği üzerinde oldukça etkili olabilir.


6

JVM'nin bitişik belleğe ihtiyacı vardır ve başka neler çalıştığına, daha önce neyin çalıştığına ve Windows'un belleği nasıl yönettiğine bağlı olarak 1,4 GB'a kadar bitişik belleğe sahip olabilirsiniz. 64bit Windows'un daha büyük yığınlara izin vereceğini düşünüyorum.


2
Modern işletim sisteminin. 80486'dan beri x86 mimarisi, fiziksel belleği yeniden düzenlemeyi kolaylaştırmak için sayfalamayı destekler.
Mnementh

3
Mnemeth: Öncelikle, WINAPI'de, belleklerini Windows dışında kendi başlarına yönetmekle daha iyi durumda olan veritabanları ve VM'ler gibi gelişmiş araçlar için belirli bir API (AllocateUserPhysicalPages) vardır. İkincisi, sayfalama 80486 değil, 80386 korumalı mod özelliğidir.
Tamas Czinege

6

Sun'ın JVM'sinin bitişik belleğe ihtiyacı var. Dolayısıyla, maksimum kullanılabilir bellek miktarı, bellek parçalanması tarafından belirlenir. Özellikle sürücü dll'leri önceden tanımlanmış bazı temel adreslere yüklenirken belleği parçalama eğilimindedir. Böylece donanımınız ve sürücüleri ne kadar bellek alabileceğinizi belirler.

Sun mühendislerinin ifadeleriyle bunun için iki kaynak: forum blogu

Belki başka bir JVM? Harmony'yi denedin mi? Sürekli olmayan belleğe izin vermeyi planladıklarını düşünüyorum.


Ancak yalnızca 1GB RAM (artı sanal bellek) olan bir makineye 1300MB ayırmayı başardım. 2GB RAM makinem (ayrıca sanal bellekli) yalnızca 1200MB ayırabilir.
Steve Kuo

Harmony öldü değil mi?
Pacerier

Evet: "Apache Harmony, 16 Kasım 2011'den beri Apache Software Foundation'da emekliye ayrılıyor."
bobbel

3

Sanırım, Windows'un bu yanıtta belirtildiği gibi nasıl yapılandırıldığıyla daha çok ilgisi var: Java -Xmx Seçeneği

Biraz daha test: Eski bir Windows XP makinesine yalnızca 768MB fiziksel RAM (artı sanal bellek) ile 1300MB ayırabildim. 2GB RAM makinemde sadece 1220MB alabiliyorum. Diğer çeşitli kurumsal makinelerde (daha eski Windows XP ile) 1400MB elde edebildim. 1220MB sınırına sahip makine oldukça yenidir (Dell'den yeni satın alınmıştır), bu nedenle belki daha yeni (ve daha şişirilmiş) Windows ve DLL'lere sahiptir (Windows XP Pro Sürüm 2002 SP2 çalıştırmaktadır).


Sanal Bellek ayarlarınızdan da etkilenebilir.
skaffman

Test ettiğim tüm makinelerde fiziksel RAM'in en az iki katı sanal bellek var.
Steve Kuo

java ile sanal belleği gerçekten kullanmak istemediğinizi unutmayın, çünkü GC performansı çok kötüleşecektir Bellek miktarı, hangi dll'lerin önceden yüklenmiş olduğuna ve belleği parçaladığına bağlıdır.
kohlerm

2

Bir (sınırlı bellek) virtüözzo VPS'den bir java programı çalıştırırken bu hata mesajını aldım. Herhangi bir bellek argümanı belirtmemiştim ve varsayılan değer çok yüksek olduğundan açıkça küçük bir miktar belirlemem gerektiğini fark ettim. Örneğin -Xmx32m (çalıştırdığınız programa bağlı olarak ayarlanması gerekir).

Soruyu soran kişinin yaptığı gibi büyük miktarda bellek belirtmeden yukarıdaki hata mesajını başka birinin alması durumunda bunu buraya koymak.


1

Sun'ın JDK / JRE'sinin, büyük bir blok ayırırsanız bitişik miktarda belleğe ihtiyacı vardır.

İşletim sistemi ve ilk uygulamalar, yükleme sırasında mevcut RAM'i parçalayan bitleri ve parçaları ayırma eğilimindedir. Bitişik bir blok mevcut DEĞİLSE, SUN JDK onu kullanamaz. Bea'dan JRockit (Oracle tarafından satın alındı) parçalardan bellek ayırabilir.


1

Herkes bitişik hafıza hakkında cevap veriyor gibi görünüyor, ancak daha acil bir sorunu kabul etmeyi ihmal etti.

% 100 bitişik bellek ayırma ile bile, 32 bit Windows işletim sisteminde 2 GiB yığın boyutuna sahip olamazsınız (varsayılan olarak *). Bunun nedeni, 32 bit Windows işlemlerinin 2 GiB'den fazla alanı ele alamamasıdır.

Java işlemi kurutma gen (Java 8 pre), iplik, JVM / kitaplık yükü başına yığın boyutunu içerir (her hangi bir yapı ile oldukça çok artar) her yığın ek olarak .

Ayrıca, JVM bayrakları ve varsayılan değerleri sürümler arasında değişir. Sadece aşağıdakileri çalıştırın ve bir fikir edineceksiniz:

 java -XX:+PrintFlagsFinal

Seçeneklerin çoğu, yığın içindeki ve dışındaki bellek bölünmesini etkiler. Sizi oynamak için aşağı yukarı 2 GiB ile bırakıyorum ...

Bu cevabımın bazı kısımlarını yeniden kullanmak için (Tomcat hakkında, ancak herhangi bir Java işlemi için geçerlidir):

Windows İşletim Sistemi, 32 bitlik bir işlemin bellek tahsisini toplamda 2 GiB ile sınırlar (varsayılan olarak).

[Yalnızca] yaklaşık 1,5 GiB yığın alanı ayırabilirsiniz çünkü işlem için ayrılmış başka bellek de vardır (JVM / kütüphane ek yükü, kalıcı alan alanı vb.).

32 bit Windows neden 2 GB işlem adres alanı sınırı koyarken 64 bit Windows 4 GB sınırı koyuyor?

Diğer modern işletim sistemleri [cough Linux], 32-bit işlemlerin 4 GiB adreslenebilir alanın tümünü (veya çoğunu) kullanmasına izin verir.

Bununla birlikte, 64 bit Windows işletim sistemleri, 32 bit işlem sınırını 4 GiB'ye (32 bit üzerinde 3 GiB) yükseltecek şekilde yapılandırılabilir:

http://msdn.microsoft.com/en-us/library/windows/desktop/aa366778(v=vs.85).aspx


1
Bu cevap sadece neden sadece 2 GB ayırabildiğini, neden bir bilgisayara 1.4 GB ve diğerine sadece 1.2 GB ayırabildiğini ele alıyor. Burada belirtilen 1.5 GB, 2 GB veya 4 GB limitlerinize ulaşmıyor.
vapcguy

1
JVM bayraklarıyla ilgili paragraf, belleğin neden sürümler arasında farklılık gösterebileceğini açıklamanın bir yolunu buluyor. Ayrıca, yığın ayarının her zaman toplam işlem boyutunun (büyük) bir bölümü olduğu konusundaki fikrime dikkat edin - bu nedenle, 2 GiB işlem sınırına hala ulaşan bir ayarın altında kalan bir ayar , bitişik bellek tahsisi ile kısıtlanabilir.
Michael

Ya da muhtemelen 1.5 GB sınırı, 1.4 GB tahsisatta yapıyor. Şimdi daha mantıklı - bu açıklama için teşekkürler.
vapcguy

0

Çağrı boyutunu nasıl artıracağınız aşağıda açıklanmıştır

  1. bilgisayarıma sağ tıklayın ---> özellikler ---> Gelişmiş
  2. performans bölümünde tıklama ayarları
  3. Gelişmiş sekmesine tıklayın
  4. Sanal bellek bölümünde değiştir'e tıklayın. Geçerli sayfalama boyutunu gösterecektir.
  5. HDD alanının mevcut olduğu Sürücü öğesini seçin.
  6. Başlangıç ​​boyutunu ve maksimum boyutu belirtin ... örn. Başlangıç ​​boyutu 0 MB ve maksimum boyut 4000 MB. (İstediğiniz kadar)

0

** Yığın boyutunu değiştirmenin birçok yolu vardır.

  1. file-> setting-> build, exceution, deployment-> derleyici burada yığın boyutunu bulacaksınız
  2. file-> setting-> build, exceution, deployment-> compiler-> andriod burada ayrıca yığın boyutunu da bulacaksınız. Aynı sorunla karşılaşırsanız, bunu andriod projesi için başvurabilirsiniz.

Benim için işe yarayan şey

  1. Java'nın güncellenmesi durumunda uygun uygun JAVA_HOME yolunu ayarlayın.

  2. yeni sistem değişkeni oluştur bilgisayar-> özellikler-> gelişmiş ayarlar- > yeni sistem değişkeni oluştur

ad: _JAVA_OPTION değer: -Xmx750m

Bilginize: varsayılan VM seçeneğini Intellij help- > özel VM'yi düzenle seçeneğinde bulabilirsiniz , Bu dosyada minimum ve maksimum yığın boyutunu görüyorsunuz. **


-1

İlk olarak, 4 GB RAM'iniz varken bir sayfa dosyası kullanmak işe yaramaz. Windows 4 GB'den (aslında bellek boşlukları nedeniyle daha az) daha fazlasına erişemediğinden, sayfa dosyası kullanılmaz.

İkinci olarak, adres alanı ikiye bölünür, çekirdek için ikiye, kullanıcı modu için ikiye bölünür. Uygulamalarınız için daha fazla RAM'e ihtiyacınız varsa, boot.ini'deki / 3GB seçeneğini kullanın (java.exe'nin "büyük adres farkında" olarak işaretlendiğinden emin olun (daha fazla bilgi için google).

Üçüncüsü, 2 GB'lık tam adres alanını ayıramayacağınızı düşünüyorum çünkü java dahili olarak bir miktar bellek boşa harcıyor (iş parçacıkları, JIT derleyicisi, VM başlatma, vb. İçin). Daha fazlası için / 3GB anahtarını kullanın.


1
Bir sayfa dosyasının 4GB veya RAM ile işe yaramaz olması fikri yanlıştır. Bir disk belleği dosyası olmadan, işletim sistemi kullanılmayan işlem verilerini (kullanılmayan hizmetler için yığın alanı, vb.) Fiziksel RAM'den çıkaramaz, böylece gerçek iş için mevcut RAM miktarını düşürür. Bir disk belleği dosyasına sahip olmak RAM'i boşaltır.
kimse
Sitemizi kullandığınızda şunları okuyup anladığınızı kabul etmiş olursunuz: Çerez Politikası ve Gizlilik Politikası.
Licensed under cc by-sa 3.0 with attribution required.