JVM 堆的定義與詳解

庸俗的情懷發表於2020-10-17

Heap 堆的定義

定義 :通過 new 關鍵字,建立物件都會使用堆記憶體

特點

  • 它是執行緒共享的,堆中物件都需要考慮執行緒安全的問題
  • 有垃圾回收機制

堆記憶體溢位

使用下面程式碼進行演示

import java.util.ArrayList;
import java.util.List;

public class heap_overflow {

	public static void main(String[] args) {
		int i = 0;
		try {
			List<String> list = new ArrayList<>();
			String a = "hello";
			while (true) {
				list.add(a); // hello, hellohello, hellohellohellohello ...
				a = a + a; // hellohellohellohello
				i++;
			}
		} catch (Throwable e) {
			e.printStackTrace();
			System.out.println(i);
		}
	}
}

在這裡對程式碼進行解釋,在new一個List物件之後,在while true死迴圈當中,每一次都會有一個值加入到list集合當中,在這裡list的作用區間在try這個裡面,也就是說當這個try程式碼塊還沒有跑完,這個list是不會被垃圾回收機制進行回收的,並且字串物件同理,是不會被回收的。所以程式碼只迴圈了25次就會丟擲異常 java.lang.OutOfMemoryError: Java heap space 這個時候因為記憶體已經佔滿。

在這裡插入圖片描述
在這裡我們也可以設定堆記憶體的大小引數,使用 -Xmx 進行設定,我們給Xmx設定為16m,再進行測試。在這篇文章有怎麼 設定引數 (eclipes)

在這裡插入圖片描述
堆記憶體診斷

  1. jps 工具
    檢視當前系統中有哪些 java 程式
  2. jmap 工具
    檢視堆記憶體佔用情況 jmap - heap 程式id
  3. jconsole 工具
    圖形介面的,多功能的監測工具,可以連續監測

在這裡使用一段程式碼進行測試:

public class heap_memory {
	public static void main(String[] args) throws InterruptedException {
		System.out.println("1...");
		Thread.sleep(30000);
		byte[] array = new byte[1024 * 1024 * 10]; // 10 Mb
		System.out.println("2...");
		Thread.sleep(20000);
		array = null;
		System.gc();
		System.out.println("3...");
		Thread.sleep(1000000L);
	}
}

在idea當中進行檢視:先演示這個jmap

在這裡插入圖片描述
而jconsole是一個圖形介面工具,同上所示,開啟後輸入命令jconsole,選擇當前執行的這個java程式,建立連線,

在這裡插入圖片描述
建立安全連線失敗,建立不安全連線。可以仔細的看到當前堆記憶體的使用。

在這裡插入圖片描述
還有一個工具 jvisualvm

在這裡插入圖片描述

相關文章