SORU
23 Kasım 2012, Cuma


Garip davranışlar Java OutOfMemoryError

256M, neden bu kod çalışmıyor maksimum bellek var varsayarsak:

public static void main(String... args) {
  for (int i = 0; i < 2; i  )
  {
      byte[] a1 = new byte[150000000];
  }
  byte[] a2 = new byte[150000000];
}

ama bu bir ÖPÜCÜK atmak?

public static void main(String... args) {
  //for (int i = 0; i < 2; i  )
  {
      byte[] a1 = new byte[150000000];
  }
  byte[] a2 = new byte[150000000];
}

CEVAP
23 Kasım 2012, Cuma


Bakış açısı sağlayacak, -Xmx64m bu kod ile çalışan göz önünde bulundurun:

static long sum;
public static void main(String[] args) {
  System.out.println("Warming up...");
  for (int i = 0; i < 100_000; i  ) test(1);
  System.out.println("Main call");
  test(5_500_000);
  System.out.println("Sum: "   sum);
}

static void test(int size) {
//  for (int i = 0; i < 1; i  )
  {
    long[] a2 = new long[size];
    sum  = a2.length;
  }
  long[] a1 = new long[size];
  sum  = a1.length;
}

Sen ısınma mı yoksa skip bağlı olarak, darbe ya da darbe değil. Bu JİTted kodu düzgün nullyorumlanmış kod yok ise var, çünkü. Hem de bu davranışları ile JVM insafına olduğunuz anlamına gelir Java Dil Şartnamesi altında kabul edilebilir.

OS X Java HotSpot(TM) 64-Bit Server VM (build 23.3-b01, mixed mode) ile test

Bayt kodu analizi

for döngü (basit kodu sum değişken olmadan): koduna bak

static void test(int);
  Code:
   0: iconst_0
   1: istore_1
   2: goto  12
   5: iload_0
   6: newarray long
   8: astore_2
   9: iinc  1, 1
   12:  iload_1
   13:  iconst_1
   14:  if_icmplt 5
   17:  iload_0
   18:  newarray long
   20:  astore_1
   21:  return

ve olmadan

static void test(int);
  Code:
   0: iload_0
   1: newarray long
   3: astore_1
   4: iload_0
   5: newarray long
   7: astore_1
   8: return

Hayır nullıng her iki durumda da dışarı açık, ama unutmayınhiç içinörnek aynı bellek konumunu aslında, aksine yenideniçinörnek. Bu, eğer bir şey, beklenti gözlenen davranış karşısında neden olurdu.

Bir sürprizle karşılaşır.

Bayt kodu dan öğrendiğimize göre, bu deneyin:

public static void main(String[] args) {
  {
    long[] a1 = new long[5_000_000];
  }
  long[] a2 = new long[0];
  long[] a3 = new long[5_000_000];
}

Hayır GEL atılmış. a2, Bildirgesi açıklama ve geri. Bizdaha ayrılamadıamakaplarlar? Bayt kodu bakın:

public static void main(java.lang.String[]);
  Code:
     0: ldc           #16                 // int 5000000
     2: istore_1      
     3: ldc           #16                 // int 5000000
     5: newarray       long
     7: astore_2      
     8: iconst_0      
     9: newarray       long
    11: astore_2      
    12: ldc           #16                 // int 5000000
    14: newarray       long
    16: astore_3      
    17: return        

Konumu a1 için kullanılan 2, a2 için kullanılmaktadır. Aynı OP kodu için de geçerlidir, ama şimdi sıfır uzunlukta zararsız bir dizi için bir referans yeri üzerine ve başka bir yerde bizim büyük dizi başvuru depolamak için kullanın.

Özetle...

Java Dil Şartnamesi herhangi bir çöp nesne belirtmiyorgerekirtoplanan ve JVM spec "" yerel değişkenler yöntemi ile tamamlayan. bir bütün olarak yok çerçeve tek diyor Bu nedenle tanık olduğumuz tüm davranışlar, kitapçı.görünmezbir nesnenin durumu (belge ile bağlantılı olarak bahsettikeppilsadece bazı durumlarda, bazı uygulamalarda ve ne olacağını anlatmak için bir yoldur, ama hiçbir şekilde kurallı herhangi bir davranıştır.

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

YORUMLAR

SPONSOR VİDEO

Rastgele Yazarlar

  • alex maybury

    alex maybury

    20 Aralık 2007
  • michaeljacksonVEVO

    michaeljacks

    2 EYLÜL 2009
  • TopDJMag TV

    TopDJMag TV

    29 Temmuz 2010