jvm的运行时数据区总结

背景介绍

为什么我会去学习去了解JVM呢,因为在学习Java的时候,在一开始就提到了JVM,说到Java不是最好的语言,但是JVM是最好的虚拟机(今天我感受到了,垃圾回收,一会不使用之后就会清楚相关的对象,其中有着相关算法可以弱化引用),一开始我认为是因为它的**一次编译,都可运行,**然后之后学习到Java的面向对象的时候,我就不这么认为了,只是认为这只是一个优点,而关键点在GC垃圾回收机制。

推荐这本书,可以在番茄上找到"剑指JVM:虚拟机实践和性能调优",通过了解这本书,我学到了一些东西,大概如下吧。

首先,我将这个区域分为了四个区域,栈、堆、方法区、程序计数器

栈(Stack)

什么是栈?借助百度百科 定义堆栈又名栈(stack),它是一种运算受限的线性表。限定仅在表尾进行插入和删除操作的线性表。这一端被称为栈顶,相对地,把另一端称为栈底。向一个栈插入新元素又称作进栈、入栈或压栈,它是把新元素放到栈顶元素的上面,使之成为新的栈顶元素;从一个栈删除元素又称作出栈或退栈,它是把栈顶元素删除掉,使其相邻的元素成为新的栈顶元素。

作为一种特殊的结构,它与递归是同种思想,总之,介绍的关键点不在他这个大的结构,而在于深入的内存结构。

虚拟机栈

虚拟机栈是JVM里的一种结构,它用来存储方法调用的状态信息(每个方法在执行过程中都会创建一个栈帧,存进虚拟机栈里面,当方法执行完的时候,就会将栈帧弹出虚拟机,就像上面说的出栈),包括局部变量表、操作数栈、动态链接、方法出口等等。

本地方法栈

这个本地方法栈和虚拟机栈很像,但是他存放的方法是本地方法,如C/C++

栈溢出总结

虚拟机栈溢出,是指虚拟机栈出现了内存溢出现象,即使用Java方法使用过多引起栈内存不足,例如无限深入递归调用方法

java 复制代码
public class StackOverflowExample {
    public static void recursiveMethod() {
        recursiveMethod();
    }

    public static void main(String[] args) {
        recursiveMethod();
    }
}

本地方法栈溢出,是指本地方法栈出现了内存溢出现象,即使用本地方法过多,如本地方法链过长

如果需要的话,读者就自己写个c语言的方法,然后方法调用自己方法本身,代码逻辑基本和虚拟机栈溢出的代码一样。

但是他们都有一个共同之处,就是栈的溢出错误(StackOverFLowError),他们都是先进后出的结构,都是线程私有的。

堆(Heap)

在JVM中,堆是用来存储对象实例和数组的内存区域,为所有线程所共享。

学到了新东西(为什么要把数组不归为对象实例之中),因为

1.可以直接强调出来他的两个存储的功能,还能存储数组这种特殊对象,避免遗漏

2.在某些情况,如处理大量数据的时候,一部分数据用普通的对象,另一部分用数组来存储,数组的存储是连续紧密的,进行垃圾回收的时候,相较于普通对象存储的方式更便捷。

行到这里就先打住这个堆的原因了,介绍新生代和老年代

新生代(Young Generation)

新生代分为三个区域,Eden、from survivor、to survivor;

Eden区:

作用:

1.创建新对象的主要区域,当new 的时候会在这里分配空间;

2.空间相对其他地方比较大,可以用来频繁创建新对象

特点:

分配对象空间的速度很快,不用复杂的内存操作,大部分对象很快就会回收。

From survivor以及To survivor区

作用:

1.存放经过一次垃圾回收后仍然存活的对象

2.他们两个会轮回交替,现在是From等会可能就是to,再等会就又变成了From

特点:

空间相对Eden区比较小,经过多次垃圾回收之后,还存活的对象会晋升到老年代

老年代(Old Generation)

作用:存储活的比较久的对象,存储新生成的大对象;

特点:空间比新生代大很多,长期存活的对象和大对象需要更多空间

垃圾回收的频率相对新生代来说低很多,垃圾回收算法与新生代不同,回收时间较长

触发回收的情况:空间不足。

方法区(Method Area)

存储已被虚拟机加载的类信息、常量、静态变量、即时编译器(jit)编译后的代码等数据的内存区域,可以理解为被识别过的数据,比较稳定的数据。

特点:

1.内存由所有线程共享,可以在不同线程访问同一个类的信息

2.相对稳定,跟栈和堆相比,数据还是比较稳定的,在程序运行期间一般不会发生变化,只有在类被卸载时才会释放方法区的内存。

3.垃圾回收,我没想到这里也有垃圾回收,主要是对不用的类进行卸载。

程序计数器(Program Counter Register)

作用:

1.指示当前执行指令的位置,他会存储当前线程正在执行的java方法的字节码指令的地址,然后当使用方法之后回来就是使用地址回来。

2。当使用另一个线程的时候结束的时候,可以指回来。

特点:

1.线程私有,每个线程都有一个

2.占用内存很小,就存一个字节码指令的地址

3.内存不会溢出,就存一个字节码指令的地址

总结

栈存储方法调用信息,堆存储对象实例,程序计数器指示执行位置,方法区存类信息等。它们相互协作,栈与堆通过对象引用关联,程序计数器与方法区配合执行指令,统一之后支持 Java 程序运行。

最关键的还是程序计数器,他就是整个流程的大脑。

如果我有哪里说得错了,希望可以指出,进步是需要的。

相关推荐
我命由我123454 小时前
Spring Boot 自定义日志打印(日志级别、logback-spring.xml 文件、自定义日志打印解读)
java·开发语言·jvm·spring boot·spring·java-ee·logback
xyliiiiiL9 小时前
ZGC初步了解
java·jvm·算法
心灵Haven13 小时前
JVM介绍
jvm
小样vvv16 小时前
【面试篇】JVM
jvm·面试·职场和发展
兢兢业业的小白鼠16 小时前
Java高级JVM知识点记录,内存结构,垃圾回收,类文件结构,类加载器
java·开发语言·jvm·tomcat
程序猿chen21 小时前
《JVM考古现场(十五):熵火燎原——从量子递归到热寂晶壁的代码涅槃》
java·jvm·git·后端·java-ee·区块链·量子计算
Song1 天前
JVM 学习计划表(2025 版)
jvm·学习
皮卡兔子屋1 天前
java虚拟机---JVM
java·jvm
可爱的霸王龙1 天前
JVM——模型分析、回收机制
java·jvm
喻米粒06221 天前
RabbitMQ消息相关
java·jvm·spring boot·spring·spring cloud·sentinel·java-rabbitmq