深入探究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/n/360319.html

(0)
打赏 微信扫一扫 微信扫一扫 支付宝扫一扫 支付宝扫一扫
KMUHYKMUHY
上一篇 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

发表回复

登录后才能评论