java.lang.OutOfMemoryError: Java yığın alanı


97

Çok iş parçacıklı bir program çalıştırılırken aşağıdaki hatayı alıyorum

java.lang.OutOfMemoryError: Java heap space

Yukarıdaki hata iş parçacıklarından birinde meydana geldi.

  1. Bildiğim kadarıyla, Yığın alanı yalnızca örnek değişkenlerle doludur. Bu doğruysa, nesne oluşturma sırasında örnek değişkenler için alan tahsis edildiğinden bir süre iyi çalıştıktan sonra bu hatanın neden oluştuğu.

  2. Yığın alanını artırmanın bir yolu var mı?

  3. Daha az yığın alanı kaplaması için programımda ne gibi değişiklikler yapmalıyım?


Yanıtlar:


105

Yığın alanınızı artırmak istiyorsanız java -Xms<initial heap size> -Xmx<maximum heap size>komut satırından kullanabilirsiniz. Varsayılan olarak değerler, JRE sürümüne ve sistem yapılandırmasına bağlıdır. Öğrenebilirsiniz Java web sitesinde VM seçenekleri hakkında daha fazla .

Bununla birlikte, yığın boyutunuzun neden yenildiğini öğrenmek için uygulamanızda profil oluşturmanızı tavsiye ederim. NetBeans, içinde çok iyi bir profil oluşturucuya sahiptir . jvisualvmKaputun altını kullandığına inanıyorum . Profil oluşturucu ile, birçok nesnenin nerede oluşturulduğunu, nesnelerin ne zaman çöp toplandığını ve daha fazlasını bulmaya çalışabilirsiniz.


1
Netbeans kullanıyorum ama profil oluşturucuyu nasıl kullanacağımı bilmiyorum. Profil oluşturucu hakkında daha fazla bilgi edinmek istiyorum, böylece onu uygulamamdaki bellek sızıntılarını bulmak için kullanabilirim.
Yatendra Goel

NetBeans sitesinde ( profiler.netbeans.org ) profil hakkında temel bilgilerden daha gelişmiş kullanıma kadar çok iyi belgelere sahip bir sayfaya bağlantı ekledim .
Thomas Owens

Varsayılan değerler java sürümlerinde değişir , cevabınıza bu bilgiyi dahil etmeniz iyi olur.
Dariusz

Sadece benzer bir sorun çözüldü ve ilk denendi: java -jar division.jar -Xmx512m -Xms512m - bu da bana aynı hatayı veriyor ama bunu yaptığımda: java -Xmx512m -Xms512m -jar division.jar - her şey yolunda. Dolayısıyla parametrelerin sırası da önemlidir.
hipokito

@hipokito Jar dosyasından sonraki bağımsız değişkenler jar dosyasının main () yöntemine bağımsız değişken olarak aktarılır []
Asu

29

1.- Evet, ancak hemen hemen programınız tarafından kullanılan belleğin tamamını ifade eder.

2.- Evet, Java VM seçeneklerine bakın

-Xms<size>        set initial Java heap size
-Xmx<size>        set maximum Java heap size

Yani

java -Xmx2g uygulamanıza maksimum 2 gigabayt ram atayın

Ama önce bir hafıza sızıntınız olup olmadığını görmelisiniz.

3.- Programa bağlıdır. Spot bellek sızıntılarını deneyin. Bu soruya cevap vermek zor olacaktır. Son zamanlarda, hafızanızın nereye gittiğini bulmak için JConsole kullanarak profil oluşturabilirsiniz.


while which (true);)
Gal Bracha

8

JVM'deki bellek hakkında daha fazla bilgi edinmek için bu siteye bakmak isteyebilirsiniz: http://developer.streamezzo.com/content/learn/articles/optimization-heap-memory-usage

Neyin değiştirileceğini belirlemek için bellek modelinin farklı bölümlerinin nasıl dolduğunu izlemek için visualgc'yi kullanmayı yararlı buldum .

Hafızanın hangi kısmının doldurulduğunu belirlemek zordur, dolayısıyla visualgc, sadece demek yerine sadece problem olan kısmı değiştirmek isteyebilirsiniz,

İnce! JVM'ye 1G RAM vereceğim.

Yaptığınız şey hakkında daha kesin olmaya çalışın, uzun vadede muhtemelen programı onun için daha iyi bulacaksınız.

Bellek sızıntısının nerede olabileceğini belirlemek için, testten önce ve sonra belleğin ne olduğunu test ederek bunun için birim testlerini kullanabilirsiniz ve çok büyük bir değişiklik varsa, o zaman onu incelemek isteyebilirsiniz, ancak yapmanız gerekir. testi testiniz devam ederken yapın.


6

Yığın boyutunu artırmak için Java'yı başlatırken -Xmx bağımsız değişkenini kullanabilirsiniz; Örneğin

-Xmx256M


6
  1. Bildiğim kadarıyla, Yığın alanı yalnızca örnek değişkenlerle doludur. Bu doğruysa, nesne oluşturma sırasında örnek değişkenler için alan tahsis edildiğinden bir süre iyi çalıştıktan sonra bu hatanın neden oluştuğu.

Bu, uygulamanızda belirli bir süre boyunca sürekli olarak daha fazla nesne oluşturduğunuz anlamına gelir. Yeni nesneler yığın belleğinde depolanacaktır ve yığın belleğindeki büyümenin nedeni budur.

Öbek yalnızca örnek değişkenleri içermez. İlkel olmayan tüm veri türlerini (Nesneler) depolar. Bu nesnelerin yaşam süresi kısa (yöntem bloğu) veya uzun olabilir (uygulamanızda nesneye başvurulana kadar)

  1. Yığın alanını artırmanın bir yolu var mı?

Evet. Daha fazla ayrıntı için bu oracle makalesine bir göz atın .

Yığın boyutunu ayarlamak için iki parametre vardır:

-Xms:, başlangıç ​​ve minimum yığın boyutunu ayarlar

-Xmx:, maksimum yığın boyutunu ayarlar

  1. Daha az yığın alanı kaplaması için programımda ne gibi değişiklikler yapmalıyım?

Uygulamanıza bağlıdır.

  1. Maksimum yığın belleğini uygulama gereksiniminize göre ayarlayın

  2. Uygulamanızda bellek sızıntılarına neden olmayın

  3. Uygulamanızda bellek sızıntıları bulursanız, MAT , Visual VM , jconsole vb . Profil oluşturma araçları yardımıyla temel nedeni bulun. Kök nedeni bulduktan sonra sızıntıları giderin.

Oracle makalesinden önemli notlar

Neden: Ayrıntı mesajı Java yığın alanı, nesnenin Java yığınında ayrılamadığını gösterir. Bu hata, mutlaka bir bellek sızıntısı olduğu anlamına gelmez.

Olası nedenler:

  1. Yanlış konfigürasyon (yeterli hafıza ayırmamak)
  2. Uygulama istemeden nesnelere referanslar tutuyor ve bu nesnelerin çöp toplanmasını engelliyor
  3. Sonlandırıcıları aşırı kullanan uygulamalar. Bir sınıfın bir finalize yöntemi varsa, bu türdeki nesnelerin alanları çöp toplama zamanında geri alınmaz. Sonlandırıcı iş parçacığı, sonlandırma kuyruğuna ayak uyduramazsa, Java yığını dolabilir ve bu tür OutOfMemoryError istisnası atılır .

Farklı bir notta, daha iyi Çöp toplama algoritmaları ( CMS veya G1GC ) kullanın

G1GC'yi anlamak için bu soruya bir göz atın


5
  1. Çoğu durumda kod optimize edilmemiştir. Daha fazla ihtiyaç duyulmayacağını düşündüğünüz nesneleri serbest bırakın. Her seferinde döngünüzde nesne oluşturmaktan kaçının. Önbellek kullanmayı deneyin. Başvurunun ne durumda olduğunu bilmiyorum. Ancak programlamada normal yaşamın bir kuralı da geçerlidir

    Korunma tedaviden daha iyidir. "Gereksiz nesneler oluşturmayın"


3
  1. Yerel değişkenler yığın üzerinde bulunur. Yığın alanı nesneler tarafından işgal edilir.

  2. -XmxSeçeneği kullanabilirsiniz .

  3. Temel olarak yığın alanı, yeni bir nesneyi her ayırdığınızda kullanılır newve nesneye artık başvurulmadığında bir süre serbest bırakılır. Bu nedenle, artık ihtiyacınız olmayan nesnelere atıfta bulunmamaya dikkat edin.


1

Hayır, bence yığın alanını düşünüyorsun. Yığın alanı nesneler tarafından işgal edilir. Arttırmanın yolu -Xmx256m'dir, 256'yı komut satırında ihtiyacınız olan miktarla değiştirir.


1

Bu istisnayı önlemek için, JUnit ve Spring kullanıyorsanız, bunu her test sınıfına eklemeyi deneyin:

@DirtiesContext(classMode = DirtiesContext.ClassMode.AFTER_CLASS)

0

Netbeans'te, 'Çalıştır' araç çubuğuna gidin, -> 'Proje Yapılandırmasını Ayarlayın' -> 'Özelleştir' -> açılan penceresinin 'çalıştır' -> 'VM Seçeneği' -> doldurun '-Xms2048m -Xmx2048m '. Yığın boyutu sorununu çözebilir.

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.