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 虚拟机栈一样,本地方法栈也可能会抛出 StackOverflowErrorOutOfMemoryError 异常。当本地方法调用层次过深或无法申请到足够的内存时,就会触发相应的异常。

相关推荐
guojl12 分钟前
Java多任务编排技术
java
丶意冷20 分钟前
mybatisPlus分页方言设置错误问题 mybatisPlus对于Oceanbase的Oracle租户分页识别错误
java·数据库·oracle·oceanbase
要开心吖ZSH1 小时前
《Spring 中上下文传递的那些事儿》Part 4:分布式链路追踪 —— Sleuth + Zipkin 实践
java·分布式·spring
桦说编程1 小时前
深入解析CompletableFuture源码实现
java·性能优化·源码
蓝澈11212 小时前
迪杰斯特拉算法之解决单源最短路径问题
java·数据结构
Kali_072 小时前
使用 Mathematical_Expression 从零开始实现数学题目的作答小游戏【可复制代码】
java·人工智能·免费
rzl022 小时前
java web5(黑马)
java·开发语言·前端
时序数据说2 小时前
为什么时序数据库IoTDB选择Java作为开发语言
java·大数据·开发语言·数据库·物联网·时序数据库·iotdb
guojl2 小时前
深度解读jdk8 HashMap设计与源码
java
guojl2 小时前
深度解读jdk8 ConcurrentHashMap设计与源码
java