JVM内存模型(JMM)

news2025/1/10 20:50:58

目录

一、运行时数据区域划分 

​编辑

二、线程私有的 

 1、程序计数器

2、虚拟机栈(VM Stack) 

3、本地方法栈 

三、线程公有的 

1、堆

2、元空间 

 

Java程序把内存控制权利交给JVM虚拟机,一旦出现内存泄漏和溢出方法的问题,如果不了解虚拟机是怎样使用内存的,那么排查错误将会是一个非常艰巨的任务,所以我们就需要来了解一下JVM内存模型。

一、运行时数据区域划分 

JVM虚拟机在执行Java程序的过程中会把它管理的内存划分成若干个不同的数据区域,JDK1.8前和JDK1.8后又有不同的划分

如图所示JDK1.8之前分为:

  • 线程共享(Heap堆区、Method Area方法区);
  • 线程私有(虚拟机栈、本地方法栈、程序计数器)

 如图所示为JDK1.8之后:

  • 线程共享(Heap堆区、MetaSpace元空间)
  • 线程私有(虚拟机栈、本地方法栈、程序计数器)

二、线程私有的 

 1、程序计数器

程序计数器是一块较小的内存空间,是当前线程所执行的字节码的行号指示器

 程序计数器的作用:

  1. 字节码解释器通过改变程序计数器来依次读取指令,从而实现代码的流程控制,如:顺序执行、选择、循环、异常处理。
  2. 在多线程的情况下,程序计数器用于记录当前线程执行的位置,从而当线程被切换回来的时候,能够知道当前线程的运行位置。

注意:程序计数器是唯一一个不会出现OutOfMemoryError 的内存区域,它随着线程的创建而创建,随着线程的结束而死亡。

2、虚拟机栈(VM Stack) 

 它的生命周期和线程相同,用于描述Java方法执行时的内存模型,每次方法调用的数据都是通过栈传递的

JMM内存区域可以粗略的区分为堆内存和栈内存。其中栈就是VM Stack虚拟机栈,或者说是虚拟机栈中局部变量表部分。

Java虚拟机栈是由一个个栈帧组成,而每个栈帧中都拥有:局部变量表、操作数栈、动态链接、方法出口信息。 

 每一次方法调用都会有一个对应的栈帧被压入 VM Stack 虚拟机栈,每一个方法调用结束后,代表该方法的栈帧会从VM Stack 虚拟机栈中弹出来

在活动线程中, 只有位于栈顶的帧才是有效的, 称为当前活动栈帧,代表正在执行的当前方法。

JVM执行引擎运行时, 所有指令都只能针对当前活动栈帧进行操作。虚拟机栈通过 poppush的方式,对每个方法对应的活动栈帧进行运算处理,方法正常执行结束,肯定会跳转到另一个栈帧上。

 

Java方法有两种返回方式,不管哪种返回方式都会导致当前活动栈帧被弹出

  • return 语句
  • 抛出异常 

Java虚拟机栈会出现两种错误:StackOverFlowErrorOutOfMemoryError 

  • StackOverFlowError 当线程请求栈的深度超过 JVM虚拟机栈的最大深度的时候,就抛出 StackOverFlowError 错误。
  • OutOfMemoryError JVM的内存大小可以动态扩展, 如果虚拟机在动态扩展栈时无法申请到足够的内存空间,则抛出OutOfMemoryError异常。

3、本地方法栈 

native关键字修饰的本地方法被执行的时候,在本地方法栈中也会创建一个栈帧,用于存放该native本地方法的局部变量表、操作数栈、动态链接、方法出口信息。方法执行完毕后,相应的栈帧也会出栈并释放内存空间。也会出现 StackOverFlowErrorOutOfMemoryError两种错误。 

三、线程公有的 

1、堆

Heap堆是JVM 所管理的内存中最大的一块区域,被所有线程共享的一块内存区域。堆区中存放对象实例,“几乎”所有的对象实例以及数组都在这里分配内存。

堆区又可以划分为新生代老年代 。目的是更好的回收内存,或者更快的分配内存。

堆的默认空间分配.jpeg

因为新生代是由 Eden + s0 + s1 组成的,所以按照上述默认比例,如果 Eden 区内存大小是 40M,那么两个 Survivor 区就是 5M,整个新生代区就是 50M,然后可以算出 老年代Old 区内存大小是 100M,堆区总大小就是 150M。 

创建对象的内存分配 

创建一个新对象,在堆中的分配内存。

大部分情况下,对象会在 Eden 区生成,当 Eden 区装填满的时候,会触发 Young Garbage Collection,即 YGC垃圾回收的时候,在 Eden 区实现清除策略,没有被引用的对象则直接回收。

依然存活的对象会被移送到 Survivor 区。Survivor 区分为 s0 s1 两块内存区域。每次 YGC的时候,它们将存活的对象复制到未使用的Survivor 空间(s0s1),然后将当前正在使用的空间完全清除,交换两块空间的使用状态。每次交换时,对象的年龄会加+1

如果 YGC 要移送的对象大于 Survivor 区容量的上限,则直接移交给老年代。一个对象也不可能永远呆在新生代,在 JVM 中 一个对象从新生代晋升到老年代的阈值默认值是 15,可以在 Survivor区交换 14 次之后,晋升至老年代。

image.png

堆区最容易出现的就是 OutOfMemoryError错误,这种错误的表现形式会有以下两种:

  1. OutOfMemoryError: GC Overhead Limit Exceeded JVM花太多时间执行垃圾回收,并且只能回收很少的堆空间时,就会发生此错误。
  2. OutOfMemoryError: Java heap space假如在创建新的对象时, 堆内存中的空间不足以存放新创建的对象, 就会引发此错误。

 

2、元空间 

用于存放类信息、常量、静态变量、JIT即时编译器编译后的机器代码等数据等。例如:java.lang.Object类的元信息、Integer.MAX_VALUE常量等。

元空间的本质和永久代类似,都是对JVM规范中方法区的一种具体实现。不过元空间与永久代之间最大的区别在于:元空间并不在虚拟机中,而是使用本地内存。因此,默认情况下,元空间的大小仅受本地内存限制,但可以通过运行参数来指定元空间的大小。

Java 8PermGen永久代为什么被移出 HotSpot JVM

  • 由于 PermGen 内存经常会溢出,容易抛出 java.lang.OutOfMemoryError: PermGen错误;
  • 移除 PermGen 可以促进 HotSpot JVMJRockit VM 的融合,因为 JRockit 没有永久代;

 

本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若转载,请注明出处:http://www.coloradmin.cn/o/1020345.html

如若内容造成侵权/违法违规/事实不符,请联系多彩编程网进行投诉反馈,一经查实,立即删除!

相关文章

Webpack使用output配置打包代码信息和自动清理打包目录

一、修改代码打包后的文件名 二、自动清理打包目录 如果我们将打包文件名修改再进行打包,会发现之前不同名的打包文件会进行保留 在output对象中配置clean属性可自动清理打包目录 三、指定打包文件的目录 四、指定多个打包文件文件名

爬虫 — 多线程

目录 一、多任务概念二、实现多任务方式1、多进程 (Multiprocessing)2、多线程(Multithreading)3、协程(Coroutine) 三、多线程执行顺序四、多线程的方法1、join()2、setDaemon()3、threading.enumerate() …

npm发布vue3自定义组件库--方法一

npm发布vue3自定义组件库 创建项目 vue create test-ui自定义组件 创建自定义组件,组件名称根据你的需求来,最好一个组件一个文件夹,下图是我的示例。 src/components 组件和你写页面一样,所谓组件就是方便实用,不…

Unity Bolt 实现UI拖拽功能

最近在学习使用Bolt插件实现五代码对UGUI Image元素实现拖拽。先看效果 录制_2023_09_15_17_50_45_29 下面是实现方式介绍: 1:注册RectTransformUtility 在使用Bolt插件实现UI拖拽的功能,需要使用 RectTransformUtility.ScreenPointToLoca…

网络安全深入学习第五课——热门框架漏洞(RCE— Apache Shiro 1.2.4反序列化漏洞)

文章目录 一、序列化和反序列化二、反序列化漏洞原理三、Apache Shiro 1.2.4反序列化漏洞1、漏洞描述:2、漏洞影响的版本3、Shiro反序列化漏洞原理4、工作原理:5、shiro反序列化的特征: 四、Apache Shiro 1.2.4反序列化漏洞手工复现1、使用DN…

做好制造项目管理的5个技巧

制造过程通常由不同的要素组成,如采购材料、与供应商合作、优化生产线效率等。制造商还需要处理库存、物流和分销。 为了确保制造项目在预算范围内按时完成,并且不遗漏任何环节,企业必须建立项目管理流程,以帮助改善组织流程和效…

社区版MyApps低代码平台,免费即刻拥有!

编者按:本文主要介绍了MyApps推出的免费社区版的优势,为企业数字化转型提供了解决方案。立即登录MyApps低代码平台,就能获取永久免费的低代码平台。 1.MyApps社区版的优势 1.1不受限制,畅享自由 无用户限制、无安装限制、全面应用…

使用 Charles 去修改响应信息(真实工作使用场景1)

目录 背景 理论 Breakpoint功能 Map功能 实践 原理 背景 测试过程中,遇到接口透传数据,修改请求中的值可以使用Postman来进行,当业务场景遇到修改响应里的值的时候,就需要借助Charles来进行。 以下将会阐述具体的步…

七天学会C语言-第三天(循环语句)

1. 用 while 语句循环做数学运算&#xff1a; 使用while语句&#xff0c;您可以创建一个循环&#xff0c;它会重复执行一段代码&#xff0c;直到指定的条件不再满足。 例 1&#xff1a; 求 246100。 #include <stdio.h>int main() {int n 1, sum 0, a 2;while (n &…

第六章 关系数据库理论

第六章 关系数据库理论 6.1 问题的提出 关系模式的表示 关系模式由五部分组成&#xff0c;是一个五元组&#xff1a;R&#xff08;U&#xff0c;D&#xff0c;DOM&#xff0c;F&#xff09;。&#xff08;1 关系名R是符号化的元组语义。U为一组属性。D为属性组U中的属性所来自…

K8s的网络——Underlay和Overlay网络

0. 基础知识 1&#xff09;网络7层基础知识 在网络7层协议基础里&#xff0c; 第一层物理链路&#xff1b;第二层是数据链路层&#xff0c;在第一层的基础上引入MAC地址做数据转发。MAC地址在局域网内具有唯一性&#xff0c;主机A发送数据时&#xff0c;会向局域网内进行广播…

idea显示git分支信息(GitToolBox插件)

效果图 说明 本身idea在右下角会有git分支信息&#xff0c;但是显示的当前打开文件的分支信息&#xff0c;并且不够显眼 解决 1、安装插件(GitToolBox插件) 2、修改idea.properties project.tree.structure.show.urlfalse ide.tree.horizontal.default.autoscrollingfalse将…

【数据结构】堆的应用+TOP-K问题+二叉树遍历

欢迎来到我的&#xff1a;世界 希望作者的文章对你有所帮助&#xff0c;有不足的地方还请指正&#xff0c;大家一起学习交流 ! 目录 前言堆的时间复杂度向下调整算法的时间复杂度向上调整算法的时间复杂度 堆的应用堆排序TOP—K问题链式二叉树二叉树的节点&#xff1a;初始化节…

ThreadLocal线程局部变量

1.原理 ThreadLocal是用来保存当前线程数据的&#xff0c;每一个线程的内部都有一个ThreadLocalMap&#xff0c;当前这个map中存储了以当前ThreadLocal作键&#xff0c;具体的数据作值的一个个Entry对象。 为什么非得以ThreadLocal对象作键呢&#xff1f;因为一个线程可能使用了…

手游联运平台是什么?

手游联运平台是一种服务于手游联运的专业平台&#xff0c;旨在为游戏开发商、发行商和代理商提供联运合作所需的技术、工具和资源。这些平台通常提供以下功能和服务&#xff1a; 游戏接入和管理&#xff1a;允许游戏开发商将他们的游戏接入联运平台&#xff0c;以便发行到不同的…

linux 环境变量详解/etc/proflie

Linux 环境变量是可以在多个文件中进行配置的&#xff0c;如/etc/proflie&#xff0c;/etc/profile.d/*.sh&#xff0c;~/.bashrc&#xff0c;~/.bash_profile等但是这些之间有什么区别呢 bash的运行模式可以分为 login shell 和 non-login shell。 例如&#xff1a;通过终端&a…

【送书活动】强势挑战Java,Kotlin杀回TIOBE榜单Top 20!学Kotlin看哪些书?

前言 「作者主页」&#xff1a;雪碧有白泡泡 「个人网站」&#xff1a;雪碧的个人网站 「推荐专栏」&#xff1a; ★java一站式服务 ★ ★ React从入门到精通★ ★前端炫酷代码分享 ★ ★ 从0到英雄&#xff0c;vue成神之路★ ★ uniapp-从构建到提升★ ★ 从0到英雄&#xff…

王道考研操作系统

王道考研操作系统 计算机系统概述操作系统的概念操作系统的特征操作系统的发展历程操作系统内核中断和异常![在这里插入图片描述](https://img-blog.csdnimg.cn/162452b4c60144e0bd500e180127c447.png)系统调用操作系统结构虚拟机错题 进程与线程进程控制进程通信线程和多线程模…

Python+Selenium定位不到元素常见原因及解决办法(报:NoSuchElementException)

这篇文章主要介绍了PythonSelenium定位不到元素常见原因及解决办法(报&#xff1a;NoSuchElementException),文中通过示例代码介绍的非常详细&#xff0c;对大家的学习或者工作具有一定的参考学习价值&#xff0c;需要的朋友们下面随着小编来一起学习学习吧 在做web应用的自动…

elasticsearch17-自动补全

个人名片&#xff1a; 博主&#xff1a;酒徒ᝰ. 个人简介&#xff1a;沉醉在酒中&#xff0c;借着一股酒劲&#xff0c;去拼搏一个未来。 本篇励志&#xff1a;三人行&#xff0c;必有我师焉。 本项目基于B站黑马程序员Java《SpringCloud微服务技术栈》&#xff0c;SpringCloud…