T: Bagaimana kebocoran memori bisa terjadi di Java?
J: Di Java, ada banyak penyebab kebocoran memori. Contoh tipikal adalah kode yang tidak mengimplementasikan hasCode dan
Kelas Kunci dari metode yang sama disimpan di HashMap. Pada akhirnya akan banyak objek duplikat yang dihasilkan. Semua memori bocor
Pada akhirnya, pengecualian OutOfMemoryError akan dilempar. Berikut adalah simulasi singkat kebocoran memori melalui loop tak terbatas.
Jelaskan dengan sebuah contoh.
Copy kode kodenya sebagai berikut:
impor java.util.HashMap;
import java.util.Map;
MemoryLeak kelas publik {
public static void main(String[] args) {
Peta<Key, String> peta = HashMap<Key, String>(1000);
int penghitung = 0;
sementara (benar) {
// membuat objek duplikat karena kelas Kunci buruk
map.put(Kunci baru("dummyKey"), "nilai");
penghitung++;
if (penghitung % 1000 == 0) {
System.out.println("ukuran peta: " + peta.ukuran());
System.out.println("Memori kosong setelah hitungan " + penghitung
+ " adalah " + getFreeMemory() + "MB");
tidur(1000);
}
}
}
// kunci kelas dalam tanpa kode hash() atau sama dengan() -- implementasi buruk
Kunci kelas statis {
kunci String pribadi;
Kunci publik(Kunci string) {
this.key = kunci;
}
}
//penundaan untuk jangka waktu tertentu dalam mili detik
public static void sleep(tidur panjangUntuk) {
mencoba {
Thread.sleep(sleepFor);
} tangkapan (InterruptedException e) {
e.printStackTrace();
}
}
//dapatkan memori yang tersedia dalam MB
getFreeMemory panjang statis publik() {
kembali Runtime.getRuntime().freeMemory() / (1024 * 1024);
}
}
Hasilnya adalah sebagai berikut:
Copy kode kodenya sebagai berikut:
ukuran peta: 1000
Memori bebas setelah hitungan 1000 adalah 4MB
ukuran peta: 2000
Memori bebas setelah hitungan 2000 adalah 4MB
ukuran peta: 1396000
Memori bebas setelah hitungan 1396000 adalah 2MB
ukuran peta: 1397000
Memori bebas setelah hitungan 1397000 adalah 2MB
ukuran peta: 1398000
Memori bebas setelah hitungan 1398000 adalah 2MB
ukuran peta: 1399000
Memori bebas setelah hitungan 1399000 adalah 1MB
ukuran peta: 1400000
Memori bebas setelah hitungan 1400000 adalah 1MB
ukuran peta: 1401000
Memori bebas setelah hitungan 1401000 adalah 1MB
.....
.....
ukuran peta: 1452000
Memori bebas setelah hitungan 1452000 adalah 0MB
ukuran peta: 1453000
Memori bebas setelah hitungan 1453000 adalah 0MB
Pengecualian di thread "utama" java.lang.OutOfMemoryError: Ruang heap Java
di java.util.HashMap.addEntry(HashMap.java:753)
di java.util.HashMap.put(HashMap.java:385)
di MemoryLeak.main(MemoryLeak.java:10)
Q: Bagaimana cara mengatasi kebocoran memori di atas?
A: Implementasikan metode equal dan hasCode dari kelas Key.
Copy kode kodenya sebagai berikut:
.....
Kunci kelas statis {
kunci String pribadi;
Kunci publik(Kunci string) {
this.key = kunci;
}
@Mengesampingkan
boolean publik sama dengan(Obj objek) {
if (obj instanceof Kunci)
return key.equals(((Key) obj).key);
kalau tidak
kembali salah;
}
@Mengesampingkan
kode hash int publik() {
kembalikan kunci.hashCode();
}
}
.....
Mengeksekusi ulang program akan menghasilkan hasil sebagai berikut:
Copy kode kodenya sebagai berikut:
ukuran peta: 1
Memori bebas setelah hitungan 1000 adalah 4MB
ukuran peta: 1
Memori bebas setelah hitungan 2000 adalah 4MB
ukuran peta: 1
Memori bebas setelah hitungan 3000 adalah 4MB
ukuran peta: 1
Memori bebas setelah hitungan 4000 adalah 4MB
...
Memori bebas setelah hitungan 73000 adalah 4MB
ukuran peta: 1
Memori bebas setelah hitungan 74000 adalah 4MB
ukuran peta: 1
Memori bebas setelah hitungan 75000 adalah 4MB
T: Dalam skenario sebenarnya, bagaimana Anda menemukan kebocoran memori?
A: Dapatkan ID thread melalui kode berikut
Copy kode kodenya sebagai berikut:
C:/>jps
5808Jps
4568 Kebocoran Memori
3860 Utama
Buka jconsole melalui baris perintah
Copy kode kodenya sebagai berikut:
C:/>jconsole 4568
Kelas Kunci yang mengimplementasikan hasCode dan sama dengan serta grafik yang tidak mengimplementasikannya adalah sebagai berikut:
Tidak ada kebocoran memori:
Penyebab kebocoran memori: