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 程序运行。

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

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

相关推荐
NEFU AB-IN5 小时前
Prompt Gen Desktop 管理和迭代你的 Prompt!
java·jvm·prompt
唐古乌梁海10 小时前
【Java】JVM 内存区域划分
java·开发语言·jvm
众俗11 小时前
JVM整理
jvm
echoyu.11 小时前
java源代码、字节码、jvm、jit、aot的关系
java·开发语言·jvm·八股
代码栈上的思考1 天前
JVM中内存管理的策略
java·jvm
thginWalker1 天前
深入浅出 Java 虚拟机之进阶部分
jvm
沐浴露z1 天前
【JVM】详解 线程与协程
java·jvm
thginWalker1 天前
深入浅出 Java 虚拟机之实战部分
jvm
程序员卷卷狗3 天前
JVM 调优实战:从线上问题复盘到精细化内存治理
java·开发语言·jvm
Sincerelyplz3 天前
【JDK新特性】分代ZGC到底做了哪些优化?
java·jvm·后端