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
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 null
yorumlanmış 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.
İle " uğraşan;java.lang.OutOfMemor...
Hata java.lang.OutOfMemoryError: GC ov...
Nasıl başa "java.lang.OutOfMemory...
java.lang.OutOfMemoryError: GC overhea...
java.lang.OutOfMemoryError: VM bütçemi...