JVM和运行时数据区

目录

运行时数据区

元空间

[Java 虚拟机栈](#Java 虚拟机栈)

[java 堆](#java 堆)

程序计数器

本地方法栈

JVM

JVM是Java Virtual Machine的简称,是java程序的运行环境(二进制字节码的运行环境)。主要由三个子系统构成,分别是类加载子系统、运行时数据区和执行引擎。

JVM结构图

运行时数据区

运行时数据区是由元空间、堆、程序计数器、虚拟机栈、本地方法栈五部分组成。

元空间

用于存储已被 JVM 加载的类信息、常量、静态变量、即时编译器编译后的代码缓存等数据的区域。被所有线程共享,多个线程可以同时访问方法区中的类信息和常量等。

在 JDK 7 及以前的实现方式,它和堆一样,都是 JVM 内存的一部分,并且有固定的大小限制。永久代不仅存储类的元数据,还存储了字符串常量池等信息。从 JDK 8 开始,永久代被元空间取代。元空间不再使用 JVM 的内存,而是使用本地内存,这使得元空间的大小不再受 JVM 内存大小的限制,而是受限于操作系统的可用内存。同时,字符串常量池从方法区移动到了堆中

在 JDK 8 之前,如果方法区(永久代)的内存设置过小,可能会导OutOfMemoryError: PermGen space 错误。在 JDK 8 及以后,如果元空间的内存使用超过了限制,会抛出OutOfMemoryError: Metaspace 错误。

Java 虚拟机栈

每个 Java 线程在创建时都会分配一个独立的虚拟机栈,用于存储方法参数和方法内部定义的局部变量。每个栈由多个栈帧组成,对应这每次方法调用时占用的内存,栈帧过多会导致栈内存溢出,常见于递归调用。

java 堆

用于保存对象实例、数组等,使得程序可以动态地创建和使用对象。为了高效地进行垃圾回收,堆通常被分为不同的区域,常见的分代垃圾回收机制将堆分为新生代和老年代。其中,新生代又可进一步细分为 Eden 区和两个 Survivor 区。新创建的对象通常会首先分配在 Eden 区,经过多次垃圾回收后仍然存活的对象会被移动到老年代。

程序在申请内存时,如果堆没有足够的内存空间供其使用,就会出现内存溢出的情况,从而导致程序抛出OutOfMemoryError异常。程序在运行过程中,如果由于某些原因导致一些不再使用的对象无法被垃圾回收器回收,一直占用内存空间,会使得可用内存逐渐减少,这时就会出现内存泄漏的情况。

程序计数器

用于保存字节码的行号,记录正在执行的字节码指令地址。每个 Java 线程都有自己独立的程序计数器,可以在执行过程中独立记录自己的执行位置,不受到其他线程的干扰。

本地方法栈

与 Java 虚拟机栈类似,本地方法栈是为虚拟机使用到的本地方法服务的。本地方法是使用非 Java 语言(如 C、C++)实现的方法,通常用于与操作系统底层交互或调用其他本地库。每个线程都有自己独立的本地方法栈,与 Java 虚拟机栈相互独立。

和 Java 虚拟机栈一样,本地方法栈也可能会抛出 StackOverflowError 和 OutOfMemoryError 异常。当本地方法调用层次过深或无法申请到足够的内存时,就会触发相应的异常。

相关推荐
Wang's Blog38 分钟前
Java 项目实战: 交友项目 - 项目:需求分析与滑动数据设计
java·开发语言·交友
前端 贾公子1 小时前
第 5 章:Codex 从可运行程序到可交付工具
java·前端·数据库
CoderYanger1 小时前
Java EE 进阶:5. Spring IoC&DI(第三弹):Spring DI
java·开发语言·spring boot·spring·面试·java-ee·mvc
一条泥憨鱼1 小时前
【Kafka】零基础学习教程
java·分布式·学习·kafka
Wang's Blog2 小时前
Java 项目实战:交友项目 - 即时通信总结:全链路复盘、可复用清单与自检
java·python·交友
文丑颜不良啊2 小时前
LeetCode1501~1520题目解析
java·leetcode
长不大的杨瑞杰2 小时前
OpenCode v2 LSP 实战:内置语言服务器、自定义配置与诊断闭环
java·人工智能·typescript·lsp·opencode
云和数据.ChenGuang2 小时前
python和java的try
java·开发语言·python
日日大王学编程2 小时前
阿里巴巴开源 Data Agent(Text2SQL)项目全维度详解
java·ai·开源
Wang's Blog2 小时前
Java 项目实战:交友项目 - 交友左滑右滑
java·交友