JDK1.8内存区域

Java内存主要分为堆、虚拟机栈、本地方法栈、程序计数器、元空间和直接内存。堆是存储对象实例和数组的主要区域,虚拟机栈服务于方法调用,每个栈帧包含局部变量表、操作数栈和动态链接。元空间存储类的元信息,避免了方法区的内存溢出问题。直接内存通过NIO库进行高效读写,但过度使用可能导致OutOfMemoryError。

摘要生成于 C知道 ,由 DeepSeek-R1 满血版支持, 前往体验 >

Java内存区域

​ 在我们Java语言,我们把内存的控制权利交给我们的JVM虚拟机

运行时内存

​ 在我们JDK1.8的版本我们

​ 线程共享的地方有堆Heap,

​ 线程私有的有虚拟机栈(VM statck)还有本地方法栈(Native mathod Stack),还有程序计数器(Program counter register)

​ 本地内存有 元空间(MateSpace) 线程共享

​ 还有直接内存 Direct Memory 线程共享

程序计数器

​ 程序计数器是一个比较小的内存空间,可以看作为当前线程所执行的字节码的行号指示灯,字节码解释器工作时候通过改变这个计数器的值选取下一条需要执行的字节码指令,分支、循环、跳转、异常处理、线程恢复等功能都是依赖这个计数器实现的。

Java虚拟机栈

​ jvm栈是jvm的核心,除了本地方法所又的方法调用都是通过栈进行实现的,每一次方法调用都需要栈进行传递,每一次方法调用都有一个对应的栈针轧入栈中,每一个方法调用结束都会弹出,每个栈帧中都有:局部变量表,操作数栈、动态链接、方法返回值

局部变量表就是我们熟知的8大数据类型还有我们的对象饮用reference类型,他不同于对象本身,可能是一个指向一个对象起始地址的引用指针,也可能是指向一个代表对象活着其他与此对象相关的位置。

​ **操作数栈:**操作数栈就是我们方法调用中转所之用的,用于存放方法执行过程中产生的中间计算结果还有计算过程中产生的临时变量。

​ **动态链接: **主要服务一个方法需要调用其他方法的场景。Class文件的常量池里保存大量的符号饮用,当一个方法调用其他方法的时候,需要将常量池中指向方法的符号引号转化为其在内存地址中的直接饮用。动态链接的作用就是为了将符号饮用转换为调用方法的直接饮用。

​ 栈内存不是无限的,当我们线程请求的栈深度超过当前java虚拟机栈的最大深度就会跑出StackOverFlowError的错误。

​ 我们的栈的内存是可以动态扩展的,如果我们无法申请到更大的内存就会跑出OutOfMemoryError异常。但是要注意我们的HotSpot虚拟机是不支持的动态扩展的,如果申请内存成功就不会抛出OutOfMemoryError,否则就会抛出。

本地方法栈

​ 本地方法栈和jvm栈一样,只不过本地方法栈是为了java服务。本地方法栈也会出现StackOverFlowErrorStackOverFlowError

​ 主要存储对象的实例和数组的内存区域,也是我们垃圾回收器主要管理的区域。

元空间

​ 在jdk1.8及以后的版本,方法区被称为元空间(Metaspace)。元空间是JVM用于存储类的元信息、常量池、静态变量、编译器优化后的代码等数据的内存区域。

在元空间中动态内存分配,内存空间是动态分配的,不会受限于固定大小, 这就意味着元空间需要动态地分配内存和释放内存,而从避免了方法区可能出现的内存溢出的问题。

在元空间类的元信息存储(类的结构、字段、方法、注解等)都是存储在本地内存的,这样就有了更大的灵活性,因为本地内存是根据需要进行调整的。

​ **在元空间类的卸载 :**在元空间中我们的原信息都是存储在本地内存的,所以更容易对类进行卸载,就也就可以让我们的程序可以动态的家在和卸载类。

​ **元空间的参数设置:**我们可以使用命令or参数对我们的jvm进行调整元空间的大小、垃圾回收策略等。这样我们就可以根据需求对我们的元空间进行调整。

​ 元空间是不会被垃圾回收的,因为它的内存是由操作系统直接分配和管理的,不是又JVM垃圾回收管理的。

运行时常量池 也叫做永久代

​ 该区域就用来存放编译期所生成的各种字面量和符号饮用。

​ 字面量就是固定值的表示法,如整数、浮点数、字符串字面量。

​ 符号引用包括类符号、字符符号引用、方法符号引用、接口方法符号。

字符串常量池

​ 字符串常量池是JVM为了提升性能和减少内存消耗针对String类专门开辟的一块区域,主要的目的就是为了避免字符串的重复创建。

直接内存

​ 直接内存是一个特殊的内存缓冲区,并不在Java堆或方法区中分配,而是通过JNI的方法在本地内存上分配的。

​ 直接内存并不是虚拟机运行时数据区的一部分,也不是虚拟机内存中规范定义的一部分。但是这块内存也会被频繁使用也会出现OutOfMemoryError错误的出现,

​ 直接内存可以通过Java的NIO库进行直接的读写操作,则无需从Java堆复制内存到直接内存。直接内存的目的就是减少java方法区的压力。

​ NIO就是一种基于Channel和Buffer的IO方法,它可以直接使用本地函数库直接分配内存,然后通过一个存储在Java堆中DirectByteBuffer对象作为这块内存的引用进行操作。这样就避免了Java堆在Native堆中来回复制数据。

数据库事务是指一组数据库操作,这些操作要么全部成功执行,要么全部失败回滚。数据库事务具有以下四个特性,通常被称为ACID特性: 1. 原子性(Atomicity):事务中的所有操作要么全部成功执行,要么全部失败回滚。如果事务中的任何一个操作失败,那么整个事务都会被回滚到初始状态。 2. 一致性(Consistency):事务执行前后,数据库的状态必须保持一致。这意味着事务中的操作必须满足数据库的约束和规则,以确保数据的完整性。 3. 隔离性(Isolation):事务的执行应该与其他事务相互隔离,互不干扰。隔离性可以防止并发事务之间的数据冲突和不一致。 4. 持久性(Durability):一旦事务提交成功,其所做的修改将永久保存在数据库中,即使系统发生故障也不会丢失。 至于JDK 1.8内存模型,它是Java虚拟机(JVM)定义的一种规范,用于描述Java程序在多线程环境下的内存访问方式。JDK 1.8内存模型引入了新的概念和规则,主要包括以下几个方面: 1.内存(Main Memory):主内存是所有线程共享的内存区域,用于存储Java对象和变量。 2. 工作内存(Working Memory):每个线程都有自己的工作内存,用于存储该线程使用的变量的副本。线程对变量的操作都是在工作内存中进行的。 3. 内存间的交互操作:线程之间通过主内存进行通信和同步。当一个线程对变量进行修改时,必须将修改后的值刷新到主内存中;当一个线程需要读取变量时,必须先从主内存中获取最新的值。 4. happens-before关系:JDK 1.8内存模型引入了happens-before关系来描述多线程之间的执行顺序。happens-before关系规定了一些操作之间的顺序性,保证了程序的可见性和一致性。
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包

打赏作者

哇塞大嘴好帅(DaZuiZui)

你的鼓励将是我创作的最大动力

¥1 ¥2 ¥4 ¥6 ¥10 ¥20
扫码支付:¥1
获取中
扫码支付

您的余额不足,请更换扫码支付或充值

打赏作者

实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值