Java bellek yönetimi

Not

Azure Spring Apps, Azure Spring Cloud hizmetinin yeni adıdır. Hizmetin yeni bir adı olsa da, ekran görüntüleri, videolar ve diyagramlar gibi varlıkları güncelleştirmek için çalışırken bazı yerlerde eski adı bir süre görürsünüz.

Bu makale şunlar için geçerlidir: ✔️ Temel/Standart ✔️ Kurumsal

Bu makalede, Azure Spring Apps'te barındırılan Java uygulamalarının davranışını anlamanıza yardımcı olmak için Java bellek yönetimiyle ilgili çeşitli kavramlar açıklanmaktadır.

Java bellek modeli

Java uygulamasının belleğinde birkaç bölüm vardır ve bölümleri bölmenin farklı yolları vardır. Bu makalede Java belleği yığın belleğine, yığın olmayan belleğe ve doğrudan belleğe bölünmüş olarak ele alınmaktadır.

Yığın belleği

Yığın bellek tüm sınıf örneklerini ve dizilerini depolar. Her Java sanal makinesi (JVM), iş parçacıkları arasında paylaşılan tek bir yığın alanına sahiptir.

Spring Boot Aktüatör yığın belleğinin değerini gözlemleyebilir. Spring Boot Aktüatör, yığın değerini öğesinin jvm.memory.used/committed/maxbir parçası olarak alır. Daha fazla bilgi için, bellek sorunlarını gidermek için araçlar bölümündeki jvm.memory.used/committed/max bölümüne bakın.

Yığın hafızası genç nesil ve eski nesillereayrılır. Bu terimler, ilgili terimlerle birlikte aşağıdaki listede açıklanmıştır.

  • Genç nesil: Tüm yeni nesneler genç nesilde ayrılır ve yaşlendirilir.

    • Eden alanı: Yeni nesneler Eden alanında ayrılır.
    • Kurtulan alanı: Nesneler, bir çöp toplama döngüsünden sonra Eden'den kurtulan alana taşınır. Kurtulan alanı iki bölüme ayrılabilir: s1 ve s2.
  • Eski nesil: tenured space olarak da adlandırılır. Uzun süre hayatta kalan alanlarda kalan nesneler eski nesile taşınacaktır.

Java 8'den önce kalıcı oluşturma adlı başka bir bölüm de yığının bir parçasıydı. Java 8'den başlayarak kalıcı nesil, yığın olmayan bellekteki meta alanla değiştirildi.

Yığın olmayan bellek

Yığın olmayan bellek aşağıdaki bölümlere ayrılır:

  • Java 8 ile başlayan kalıcı neslin (veya permGen'in) yerini alan yığın olmayan belleğin bölümü. Spring Boot Aktüatör bu bölümü gözlemler ve öğesinin jvm.memory.used/committed/maxbir parçası olarak alır. Başka bir deyişle, jvm.memory.used/committed/max yığın belleğinin toplamı ve yığın olmayan belleğin eski permGen kısmıdır. Eski kalıcı nesil aşağıdaki bölümlerden oluşur:

    • Sınıf yükleyicileri tarafından yüklenen sınıf tanımlarını depolayan meta alan.
    • Sıkıştırılmış sınıf işaretçileri için sıkıştırılmış sınıf alanı.
    • JIT tarafından derlenen yerel kodu depolayan kod önbelleği.
  • Spring Boot Aktüatör tarafından gözlemlenmemiş iş parçacığı yığını gibi diğer bellek.

Doğrudan bellek

Doğrudan bellek, tarafından ayrılan java.nio.DirectByteBufferyerel bellektir ve nio ve gzip gibi üçüncü taraf kitaplıklarında kullanılır.

Spring Boot Aktüatör doğrudan bellek değerini gözlemlemez.

Aşağıdaki diyagramda, önceki bölümde açıklanan Java bellek modeli özetlemektedir.

Java bellek modelini gösteren diyagram.

Java çöp toplama

Java Çöp Toplama (GC) ile ilgili üç terim vardır: "Minor GC", "Major GC" ve "Full GC". Bu terimler JVM belirtiminde açıkça tanımlanmamıştır. Burada "Major GC" ve "Full GC" değerleri eşdeğer olarak kabul ediyoruz.

Eden alanı dolduğunda ikincil GC işlemi gerçekleştirir. Genç nesildeki tüm ölü nesneleri kaldırır ve canlı nesneleri Eden uzayından kurtulan uzayın s1'ine veya s1'den s2'ye taşır.

Tam GC veya ana GC, yığının tamamında çöp toplama işlemi yapar. Tam GC, meta alan ve doğrudan bellek gibi parçaları da toplayabilir ve bu parçalar yalnızca tam GC tarafından temizlenebilir.

Maksimum yığın boyutu, küçük GC ve tam GC sıklığını etkiler. Maksimum meta alan ve maksimum doğrudan bellek boyutu tam GC'yi etkiler.

En büyük yığın boyutunu daha düşük bir değere ayarladığınızda çöp toplama işlemleri daha sık gerçekleşir ve bu da uygulamayı biraz yavaşlatsa da bellek kullanımını daha iyi sınırlar. En büyük yığın boyutunu daha yüksek bir değere ayarladığınızda, atık toplama işlemleri daha az sıklıkta gerçekleşir ve bu da daha fazla bellek yetersiz (OOM) riski oluşturabilir. Daha fazla bilgi için bellek yetersiz sorunlarının neden olduğu Uygulama yeniden başlatma sorunlarının Bellek yetersiz sorunları türleri bölümüne bakın.

Meta alan ve doğrudan bellek yalnızca tam GC tarafından toplanabilir. Meta uzay veya doğrudan bellek dolduğunda, tam GC gerçekleşir.

Java bellek yapılandırmaları

Aşağıdaki bölümlerde Java bellek yapılandırmasının önemli yönleri açıklanmaktadır.

Java kapsayıcısı

Azure Spring Apps'teki uygulamalar kapsayıcı ortamlarında çalışır. Daha fazla bilgi için bkz . Java uygulamalarınızı kapsayıcıya alma.

Önemli JVM seçenekleri

JVM seçeneklerini kullanarak belleğin her parçasının en büyük boyutunu yapılandırabilirsiniz. Azure CLI komutlarını kullanarak veya Azure portalı aracılığıyla JVM seçeneklerini ayarlayabilirsiniz. Daha fazla bilgi için, Bellek sorunlarını gidermek için araçlar'ın Sorunları gidermek için yapılandırmaları değiştirme bölümüne bakın.

Aşağıdaki listede JVM seçenekleri açıklanmaktadır:

  • Yığın boyutu yapılandırması

    • -Xms ilk yığın boyutunu mutlak değere göre ayarlar.
    • -Xmx maksimum yığın boyutunu mutlak değere göre ayarlar.
    • -XX:InitialRAMPercentage , ilk yığın boyutunu yığın boyutu /uygulama bellek boyutu yüzdesine göre ayarlar.
    • -XX:MaxRAMPercentage en büyük yığın boyutunu, yığın boyutu /uygulama bellek boyutu yüzdesine göre ayarlar.
  • Doğrudan bellek boyutu yapılandırması

    • -XX:MaxDirectMemorySize maksimum doğrudan bellek boyutunu mutlak değere göre ayarlar. Daha fazla bilgi için Oracle belgelerinde MaxDirectMemorySize bölümüne bakın.
  • Meta alan boyutu yapılandırması

    • -XX:MaxMetaspaceSize maksimum meta alan boyutunu mutlak değere göre ayarlar.

Varsayılan en büyük bellek boyutu

Aşağıdaki bölümlerde varsayılan en büyük bellek boyutlarının nasıl ayarlandığı açıklanmaktadır.

Varsayılan en büyük yığın boyutu

Azure Spring Apps, Java uygulamaları için varsayılan maksimum yığın bellek boyutunu uygulama belleğinin yaklaşık %50-%80'ine ayarlar. Azure Spring Apps özellikle aşağıdaki ayarları kullanır:

  • Uygulama belleği < 1 GB ise, varsayılan maksimum yığın boyutu uygulama belleğinin %50'sini oluşturur.
  • 1 GB <= uygulama belleği < 2 GB ise, varsayılan maksimum yığın boyutu uygulama belleğinin %60'ı olur.
  • 2 GB <= uygulama belleği < 3 GB ise varsayılan maksimum yığın boyutu uygulama belleğinin %70'i olur.
  • 3 GB <= uygulama belleği ise varsayılan maksimum yığın boyutu uygulama belleğinin %80'i olur.

Varsayılan en büyük doğrudan bellek boyutu

En büyük doğrudan bellek boyutu JVM seçenekleri kullanılarak ayarlanmıyorsa, JVM en büyük doğrudan bellek boyutunu Runtime.getRuntime.maxMemory() tarafından döndürülen değere otomatik olarak ayarlar. Bu değer, en büyük yığın bellek boyutuna yaklaşık olarak eşittir. Daha fazla bilgi için bkz . JDK 8 VM.java dosyası.

Bellek kullanımı düzeni

Yığın boyutu, aktarım hızınızdan etkilenir. Temel olarak, yapılandırırken varsayılan maksimum yığın boyutunu koruyabilirsiniz ve bu da diğer parçalar için makul bellek bırakır.

Meta alan boyutu, sınıf sayısı gibi kodunuzun karmaşıklık düzeyine bağlıdır.

Doğrudan bellek boyutu, aktarım hızınıza ve nio ve gzip gibi üçüncü taraf kitaplıkları kullanımınıza bağlıdır.

Aşağıdaki listede 2 GB'lık uygulamalar için tipik bir bellek düzeni örneği açıklanmaktadır. Bellek boyutu ayarlarınızı yapılandırmak için bu listeye başvurabilirsiniz.

  • Toplam Bellek (2048M)
  • Yığın belleği: Xmx 1433,6M'dir (toplam belleğin %70'i). Günlük bellek kullanımının başvuru değeri 1200M'dir.
    • Genç nesil
      • Kurtulan alan (S0, S1)
      • Eden alanı
    • Eski nesil
  • Yığın olmayan bellek
    • Gözlemlenen bölüm (Spring Boot Aktüatör tarafından gözlemlenir)
      • Meta alan: Günlük kullanım başvuru değeri 50M-256M'dir
      • Kod önbelleği
      • Sıkıştırılmış sınıf alanı
    • Gözlemlenmeyen bölüm (Spring Boot Aktüatör tarafından gözlemlenmez): Günlük kullanım başvuru değeri 150M-250M'dir.
      • İş parçacığı yığını
      • GC, iç simge ve diğer
  • Doğrudan bellek: Günlük kullanım başvuru değeri 10M-200M'dir.

Aşağıdaki diyagramda aynı bilgiler gösterilmektedir. Gri renkli sayılar, günlük bellek kullanımının başvuru değerleridir.

2 GB'lık uygulamalar için tipik bellek düzeni diyagramı.

Genel olarak, en büyük bellek boyutlarını yapılandırırken bellekteki her bölümün kullanımını göz önünde bulundurmanız gerekir ve tüm maksimum boyutların toplamı toplam kullanılabilir belleği aşmamalıdır.

Java OOM

OOM, uygulamanın belleğinin yetersiz olduğu anlamına gelir. İki farklı kavram vardır: kapsayıcı OOM ve JVM OOM. Daha fazla bilgi için bkz . Yetersiz bellek sorunlarının neden olduğu uygulama yeniden başlatma sorunları.

Ayrıca bkz.