深入探究Java中的Nonheap

一、Nonheap介紹

Java虛擬機將內存劃分為兩個區域:heap和nonheap。

Heap區用於存儲Java對象和JVM需要管理的數據。

Nonheap區用於存儲JVM本身和Java類相關的信息。

除了Static數據和代碼區,其他的Java代碼都在Heap中運行。

而非Java數據的JVM或者Java類定義等信息是存儲在Nonheap中的。

二、Nonheap的組成

Java中的Nonheap主要由Java虛擬機自己管理。

主要包含以下幾個主要的元素:

1. Code Cache

Code Cache存放被JIT編譯後的本地代碼(native code)。

2. PermGen Space

PermGen Space存儲Java類信息(例如類名稱、訪問修飾符等),以及方法和字段的元數據信息。

3. Metaspace

Java SE 8中,PermGen space被Metaspace替換,因為PermGen space在過多使用時會導致內存問題。所以,Metaspace用來存放類元信息。

4. Stack

Stack中存儲着線程的運行狀態,包括方法調用堆棧、局部變量信息和操作數棧。

5. Direct Buffers

Direct Buffers是non-heap的一部分。

6. JNI

Java Native Interface,是Java中調用非Java的C或其他本地庫的接口。

三、代碼示例

class NonHeapDemo{
    public static void main(String[] args) {
        //查找NonHeap區Header容量 
        long nonheapHeaderSize = sun.misc.VM.maxDirectMemory() - sun.misc.VM.currentDirectMemory();
        System.out.println("NonHeap Header Size: " + nonheapHeaderSize);

        //獲取Code Cache大小
        long codeCacheSize = ((com.sun.management.HotSpotDiagnosticMXBean) ManagementFactory.getDiagnosticMXBean()).getLargestCompilationLevel();
        System.out.println("Code Cache Size: " + codeCacheSize);

        //獲取PermGen Space或者Metaspace的大小
        long metaspaceSize = ((com.sun.management.GarbageCollectorMXBean) ManagementFactory.getGarbageCollectorMXBeans().get(0)).getMemoryPoolNames().stream()
                .filter(pool -> pool.contains("Metaspace"))
                .map(ManagementFactory::getMemoryPoolMXBean)
                .mapToLong(MemoryPoolMXBean::getUsage).mapToLong(Usage::getMax).sum();
        System.out.println("PermGen Space/Metaspace Size: " + metaspaceSize);

        //獲取Direct Buffers大小
        long directBufferSize = ((com.sun.management.BufferPoolMXBean) ManagementFactory.getPlatformMXBeans(BufferPoolMXBean.class).get(0)).getTotalCapacity();
        System.out.println("Direct Buffer Size: " + directBufferSize);

        //獲取JNI信息
        System.out.println("JNI: " + sun.misc.SharedSecrets.getJavaLangAccess().getJNIMethods().size());
    }
}

四、Nonheap的重要性

Nonheap對Java應用的運行也有很大的影響。

例如,Nonheap中的Direct Buffers如果不管控得當,會導致應用內存泄漏,最終導致JVM崩潰。

而且,PermGen Space也需要注意大小,因為如果PermGen Space不足,可能會導致「內部錯誤:Java堆空間溢出」,這是因為PermGen的比例比例比例如今應用的內存。

因此,掌握Nonheap的基本知識和調優方法是十分重要的。

原創文章,作者:KMUHY,如若轉載,請註明出處:https://www.506064.com/zh-hk/n/360319.html

(0)
打賞 微信掃一掃 微信掃一掃 支付寶掃一掃 支付寶掃一掃
KMUHY的頭像KMUHY
上一篇 2025-02-24 00:33
下一篇 2025-02-24 00:33

相關推薦

  • Java JsonPath 效率優化指南

    本篇文章將深入探討Java JsonPath的效率問題,並提供一些優化方案。 一、JsonPath 簡介 JsonPath是一個可用於從JSON數據中獲取信息的庫。它提供了一種DS…

    編程 2025-04-29
  • java client.getacsresponse 編譯報錯解決方法

    java client.getacsresponse 編譯報錯是Java編程過程中常見的錯誤,常見的原因是代碼的語法錯誤、類庫依賴問題和編譯環境的配置問題。下面將從多個方面進行分析…

    編程 2025-04-29
  • Java騰訊雲音視頻對接

    本文旨在從多個方面詳細闡述Java騰訊雲音視頻對接,提供完整的代碼示例。 一、騰訊雲音視頻介紹 騰訊雲音視頻服務(Cloud Tencent Real-Time Communica…

    編程 2025-04-29
  • Java Bean加載過程

    Java Bean加載過程涉及到類加載器、反射機制和Java虛擬機的執行過程。在本文中,將從這三個方面詳細闡述Java Bean加載的過程。 一、類加載器 類加載器是Java虛擬機…

    編程 2025-04-29
  • Java Milvus SearchParam withoutFields用法介紹

    本文將詳細介紹Java Milvus SearchParam withoutFields的相關知識和用法。 一、什麼是Java Milvus SearchParam without…

    編程 2025-04-29
  • Java 8中某一周的周一

    Java 8是Java語言中的一個版本,於2014年3月18日發佈。本文將從多個方面對Java 8中某一周的周一進行詳細的闡述。 一、數組處理 Java 8新特性之一是Stream…

    編程 2025-04-29
  • Java判斷字符串是否存在多個

    本文將從以下幾個方面詳細闡述如何使用Java判斷一個字符串中是否存在多個指定字符: 一、字符串遍歷 字符串是Java編程中非常重要的一種數據類型。要判斷字符串中是否存在多個指定字符…

    編程 2025-04-29
  • VSCode為什麼無法運行Java

    解答:VSCode無法運行Java是因為默認情況下,VSCode並沒有集成Java運行環境,需要手動添加Java運行環境或安裝相關插件才能實現Java代碼的編寫、調試和運行。 一、…

    編程 2025-04-29
  • Java任務下發回滾系統的設計與實現

    本文將介紹一個Java任務下發回滾系統的設計與實現。該系統可以用於執行複雜的任務,包括可回滾的任務,及時恢復任務失敗前的狀態。系統使用Java語言進行開發,可以支持多種類型的任務。…

    編程 2025-04-29
  • Java 8 Group By 會影響排序嗎?

    是的,Java 8中的Group By會對排序產生影響。本文將從多個方面探討Group By對排序的影響。 一、Group By的概述 Group By是SQL中的一種常見操作,它…

    編程 2025-04-29

發表回復

登錄後才能評論