JVM内存模型简解

本文详细介绍了JVM内存模型的各个组成部分,包括线程私有区域(程序计数器、虚拟机栈、本地方法栈)和线程共享区域(堆、方法区)。解释了每个部分的功能、特点及异常处理,帮助读者深入了解JVM内存管理机制。

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

简单的介绍一下jvm内存模型共勉

根据上图可以将运行时数据区分为两个部分:1、线程私有区域(1、程序计数器;2、虚拟机栈;3、本地方法栈)。2、线程共享区域(1、堆;2、方法区)。
下面来分别的介绍一下;

一、线程私有区域

1、程序计数器

程序计数器是一块较小的内存空间,他可以看做是当前线程所执行的字节码的行号指示器;在虚拟机的概念模型里,字节码解析器工作时,通过改变这个计数器的值来选取下一条需要执行的字节码指令,分支、循环、跳转、异常处理、线程恢复等基础功能都需要依赖这个计数器来完成。
有什么特点:
线程私有的;
是java虚拟机规范里面,唯一一个没有规定任何OutOfMemoryError 情况的区域;
声明周期随着线程,线程启动而产生,线程结束而消失。
重点理解:程序计数器,可以看做是当前线程执行的字节码的行号指示器
在这里插入图片描述
上面的标注数字,就是类似于字节码的行号(实际是指令的偏移地址),程序计数器中保存中的值;字节码解析器就是根据它们来执行程序。
列如:java是支持多线程的,当CPU执行权从A线程,转移到B线程的时候,JVM就要暂时挂起线程A,去执行线程B;当线程A再次得到CPU执行权的时候,有会挂起B线程,继续执行A线程;

可以想一下CPU是怎么知道记住之前A线程执行到哪一处的呢?
CPU根本不会记住之前执行到哪里了,他只知道干活那么是什么保证了切换线程的程序可以正常执行的;程序计数器就是解决这些问题的。程序计数器里面保存的是当前线程执行的字节码的行号;
那么如上面的两个线程不断切换我们序号几个程序计数器呢?两个,因为当线程B有一个计数器而A没有的话从B切换到A记住了B当前的行号数,再从B切换到A是就会混乱。所以每个线程都分配一个程序计数器,因此,程序计数器的内存空间是线程私有的即使两个线程之间来回切换也不会发生混乱。

什么时候进行创建程序计数器呢?一个线程在执行的任何期间,都会失去CPU执行权,因此从一个线程被创建开始执行,
就要无时无刻的记录着线程当前执行到哪里了! 因此,线程计数器,必须是线程被创建开始执行的时候,就要一同被创建;

程序计数器,保存的是当前执行的字节码的偏移量地址(也就是之前说的行号,其实那不是行号,是指令的偏移量,只是为了好理解才那样说的)当执行到下一条指令的时候改变的只是程序计数器中保存的地址,并不需要申请新的内存来保存新的指令地址;因此,永远都不可能内存溢出的;jvm虚拟机规范,也就没有规定,也是唯一一个没有规定OutOfMemoryError 异常的区域;

2、虚拟机栈:

虚拟机栈是线程私有的,每创建一个线程,虚拟机就会为这个线程创建一个虚拟机栈,虚拟机栈表示Java方法执行的内存模型,每调用一个方法就会为每个方法生成一个栈帧(Stack Frame),用来存储局部变量表、操作数栈、动态链接、方法出口等信息。每个方法被调用和完成的过程,都对应一个栈帧从虚拟机栈上入栈和出栈的过程。虚拟机栈的生命周期和线程是相同的。
方法调用时,创建栈帧,并压入虚拟机栈;方法执行完毕,栈帧出栈并被销毁。
在这里插入图片描述
虚拟机栈是线程隔离的,即每个线程都有自己独立的虚拟机栈。
虚拟机栈的StackOverflowError
若每个线程请求的栈深度大于虚拟机允许的深度,则会抛出StackOverflowError(栈溢出错误)。
JVM会为每个线程的虚拟机栈分配一定的内存大小,因此虚拟机栈能够容纳的栈帧数量时有限的,若栈帧不断进栈而不出栈,最终会导致当前线程虚拟机栈的内存空间耗尽。如一个没有结束条件的递归函数调用或使用JPA时出现循环引用。
虚拟机栈的OutOfMemoryError
不同于StackOverflowError,OutOfMemoryError指的是当整个虚拟机栈内存耗尽,并且无法再申请到新的内存时抛出的异常。
JVM未提供设置整个虚拟机栈占用内存的配置参数。虚拟机栈的最大内存大致上等于“JVM进程能占用的最大内存(依赖于具体操作系统) - 最大堆内存 - 最大方法区内存 - 程序计数器内存(可以忽略不计) - JVM进程本身消耗内存”。当虚拟机栈能够使用的最大内存被耗尽后,便会抛出OutOfMemoryError,可以通过不断开启新的线程来模拟这种异常。

3、本地方法栈:

本地方法栈的功能和特点类似于虚拟机栈,均具有线程隔离的特点以及都能抛出StackOverflowError和OutOfMemoryError异常。
  不同的是,本地方法栈服务的对象是JVM执行的native方法,而虚拟机栈服务的是JVM执行的java方法。如何去服务native方法?native方法使用什么语言实现?怎么组织像栈帧这种为了服务方法的数据结构?虚拟机规范并未给出强制规定,因此不同的虚拟机实可以进行自由实现,我们常用的HotSpot虚拟机选择合并了虚拟机栈和本地方法栈。

二、线程共享区域

1、堆:

存储的全部对象,每个对象都包含一个与之对应的class的信息;
jvm只有一个heap区,被所有线程共享,不存放基本类型和对象引用,只存放对象本身。
堆的优势:
堆的优势是可以动态的分配内存大小,生存期也不必要事先告诉编译器,java的垃圾收集器会自动收取这些不在使用的数据
缺点:由于要在运行时动态分配内存,存取速度慢。

java堆是所有线程所共享的一块内存,在虚拟机启动时创建,几乎所有的对象实例都在这里创建,因此该区域经常发生垃圾回收操作。 1.根据Java虚拟机规范,JVM将内存划分为:
New(年轻代) Tenured(年老代) 永久代(Perm)

垃圾回收器主要回收的是堆区中未使用的内存区域,并对相应的区域进行整理。在堆区中,又根据对象内存的存活时间或者对象大小,分为“新生代”和“老年代”。“新生代”中的对象是不稳定的易产生垃圾,而“老年代”中的对象比较稳定,不易产生垃圾。之所以将其分开,是分而治之,根据不同区域的内存块的特点,采取不同的内存回收算法,从而提高堆区的垃圾回收的效率。
元空间:
存储类和类加载器的元数据信息

在这里插入图片描述
新建的对象会存放在年轻代里面,,年轻代填满会触发minor gc,minor gc会清除包含s0,s1在内的所有年轻代里面不用的垃圾。
在这里插入图片描述
Eden里面没用被清除的对象就会幸存下来的,就会被放入s0或者s1中,每次所有新村对象必须放入一个survivor space区域,意味着必须有一个survivor space是空的。对象上面的数字代表他的年龄,即幸存的次数每次幸存以后都会换survivor space,并且年龄+1。
当幸存对象 的年龄到达某个值后,就会从年轻代进入老年代。
永恒代,放常用库文件和方法

Eden和survivor的比例为8:1,老年代比年轻代内存大。如果老年代内存满了,就会触发major GC或者full GC。触发full GC就会出现所谓的STW(stop the world)现象。即所有的进程都挂起等待清理垃圾。

major GC是回收老年代的垃圾。Full GC是回收老年代和年轻代的垃圾。

2、方法区:

方法区又称为永久代,常称为PermGen,位于非堆空间,又称为非堆区。
方法区是被所有线程共享。
素有字段和方法字节码,以及一些特殊方法如构造函数,接口代码也在此定义。
简单说,所有定义的方法的信息都保存在该区域,此区域属于共享区间。
静态变量+常量+类信息(构造方法/接口定义)+运行时常量池存在方法区中。
但是, 实例变量 存在 堆内存 中,和方法区无关。
只是逻辑上的定义。在HotSpot中,方法区仅仅只是逻辑上的独立,实际上还是包含在Java堆中,也是就说,方式区在物理上属于Java堆区中的一部分,而永久区(Permanent Generation)就是方法区的实现。

内容概要:本文档提供了关于“微型车间生产线的设计与生产数据采集试验研究”的毕业设计复现代码,涵盖从论文结构生成、机械结构设计、PLC控制系统设计、生产数据采集与分析系统、有限元分析、进度管理、文献管理和论文排版系统的完整实现。通过Python代码和API调用,详细展示了各个模块的功能实现和相互协作。例如,利用SolidWorks API设计机械结构,通过PLC控制系统模拟生产流程,使用数据分析工具进行生产数据的采集和异常检测,以及利用进度管理系统规划项目时间表。 适合人群:具有机械工程、自动化控制或计算机编程基础的学生或研究人员,尤其是从事智能制造领域相关工作的人员。 使用场景及目标:①帮助学生或研究人员快速搭建和理解微型车间生产线的设计与实现;②提供完整的代码框架,便于修改和扩展以适应不同的应用场景;③作为教学或科研项目的参考资料,用于学习和研究智能制造技术。 阅读建议:此资源不仅包含详细的代码实现,还涉及多个学科领域的知识,如机械设计、电气控制、数据分析等。因此,在学习过程中,建议读者结合实际操作,逐步理解每个模块的功能和原理,并尝试调整参数以观察不同设置下的系统表现。同时,可以参考提供的文献资料,深入研究相关理论和技术背景。
本次的学生体质健康信息管理网站,按照用户的角色可以分为教师与学生,后台设置管理员角色来对学生的信息进行管理。,设计如下: 1、后台管理系统 后台管理系统主要是为该系统的管理员提供信息管理服务的系统,具体包括的功能模块如下: (1)管理员信息管理 (2)教师信息管理 (3)学生信息管理 (4)健康信息统计(图形化进行健康,亚健康等学生的信息数量统计) 2、教师角色的功能模块设计 教师角色所需要的功能模块主要包括了如下的一些内容: (1)个人资料修改 (2)学生体质健康管理:录入相关数据,包括但不限于身高、体重、肺活量、视力等生理指标以及运动能力、身体成分、骨密度等健康指标,并且设置健康,亚健康状态 (3)学生健康建议:根据体质信息,进行学生健康的建议 (4)健康预警:对健康出问题的学生,进行健康预警 (5)饮食和锻炼情况管理,查看 3、学生角色 学生角色可以通过该信息网站看到个人的基本信息,能够看到教师给与学生的健康建议等,功能模块设计如下: (1)个人资料修改 (2)我的健康建议查看 (3)我的健康预警 (4)饮食和锻炼情况管理,记录平时的饮食和锻炼情况 完整前后端源码,部署后可正常运行! 环境明 开发语言:Java后端 框架:ssm,mybatis JDK版本:JDK1.8+ 数据库:mysql 5.7+ 数据库工具:Navicat11+ 开发软件:eclipse/idea Maven包:Maven3.3+ 部署容器:tomcat7.5+
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

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

余额充值