当前位置:首页 > Java技术 > JVM内存模型及内存分配

JVM内存模型及内存分配

2022年11月07日 13:28:15Java技术6

JVM内存模型

首先先让我们看看内存结构图
JVM内存模型及内存分配 _ JavaClub全栈架构师技术笔记

然后我们来具体介绍下每一部分的内容:

类加载器

之前有一篇文章讲解了有关类加载的机制,在这里就不再赘述了,有需要的朋友请移步查看

虚拟机栈

虚拟机栈描述的是Java方法执行的动态内存模型,虚拟机栈中最重要的就是栈帧的概念

栈帧

每个方法的执行,都会创建一个栈帧,伴随着方法从创建到执行完成,栈帧中有局部变量表、操作数栈、动态链接,方法出口等

局部变量表

存放编译期可知的各种基本数据类型,引用类型,returnAddress类型(仅存在于字节码层面,returnAddress类型的值就是指向特定指令内存地址的指针)
局部变量表的内存空间在编译期分配完成,在进入一个方法时,这个方法需要在栈帧中分配的内存大小是固定的,在方法运行期间不会改变局部变量表的大小,任何会改变大小的对象都会使用引用类型来指定

操作数栈

Java虚拟机的解释执行引擎被称为"基于栈的执行引擎",其中的栈就是操作数栈,虚拟机把操作数栈作为他的工作区,大多数指令都要从这里弹出数据,执行运算,然后把结果压回操作数栈

动态链接

每一次运行期间,都会转化为字节引用,指向运行时常量池中该栈帧所属方法的引用

方法返回地址

方法执行结束后应该回到哪一行字节码继续执行,该地址的获取有两种方式,一是方法正常退出通过PC计数器获取,另一个则是方法执行发生异常后通过异常处理表获取

本地方法栈

和虚拟机栈类似,最大的不同就是本地方法用于本地方法的调用,即native修饰的方法,JVM允许Java直接调用本地方法(由C语言编写)

程序计数器

程序计数器是一块比较小的内存空间,他可以看作是当前线程所执行的字节码的行号指示器
在任意时刻,一个线程总是在执行一个方法,这个方法称为当前方法,如果线程执行的是Java方法,这个计数器记录的是正在执行的虚拟机字节码指令的地址,如果正在执行的是native方法,则程序计数器的值为undefined

Java堆

Java堆解决的是数据存储的问题,几乎所有的对象实例都存放在Java堆中
堆内存分为新生代和老年代(Tenured Gen),分配比例默认为1:2
其中新生代又分为Eden和两个Survivor区(From和To),分配的默认比例为8:1:1

方法区

方法区是辅助Java堆的一块内存区域,用于存储虚拟机加载的类信息、常量、运行时常量池、即时编译器(JIT)编译后的代码等数据

JVM中特殊的内存区域

运行时常量池(隶属于方法区)

存放编译期生成的各种字面量和符号引用,这部分内容将在类加载后进入方法区(共享内存区)的运行时常量池存放,其中的字面量(字符串常量)会被存放到一个字符串表中,该表为HashSet类型,具有无序不可重复的特点,所以相同的字面常量自然就是同一块内存地址,通过new的方式创建的同字面量字符串不会考虑常量池的对象,而是直接在堆中重新开辟一块内存空间,所以必然和常量池对象地址不同

直接内存

在NIO中会使用到直接内存用于提高IO性能,其他地方几乎是不用的,通常直接内存速度会优于java堆,读写频繁的场合可能会考虑使用
直接内存不受制JVM堆内存的制约,但是依旧受限于物理内存的制约,如果内存满了也会抛出OutOfMemoryError异常
不过可以调用String对象的intern()方法实现运行时加入常量池,从而实现System.out.println("str"==new String("str").intern())的输出为true

JVM内存分配

内存分配策略

优先分配到Eden

测试方法:在方法中直接分配一个不超过Eden总内存的大对象,通过打印GC信息来查看是否是在Eden区分配的内存

大对象直接分配到老年代

当新对象的大小超出了Eden的内存上限,将直接在老年代中给该对象分配内存

空间分配担保,默认是开启的,可以通过-XX:-HandlePromotionFailure来关闭

当Eden区的空间已不足以存放新建对象,而且Survivor中空间也不够时(必然不够),只能将原有新生代的内容直接存放到老年代中,从而给新对象腾出足够的空间

动态对象年龄判断

对于在From和To两个Survivor区流转的对象,当流转次数达到某个值时(默认为15),会被存入到老年代中

逃逸分析和栈上分配

栈上分配

Java栈的方法执行完成后会自动释放空间,所以如果将方法中的局部变量直接在栈中进行分配,在方法执行完毕时,对象会跟随方法释放掉,不需要垃圾收集器的介入,可以提高程序效率

逃逸分析

对于一个方法中的变量,分析其作用域,只要能够确定该变量没有方法外的引用,那就说明该变量没有发生逃逸,也就可以使用栈上分配

对象的创建流程

先尝试栈上分配,满足则分配,不满足尝试TLAB(Thread Local Allocation Buffer)分配,满足则分配,不满足查看是否满足进入老年代,满足则在老年区进行分配,不满足则在Eden区进行分配

TLAB,称为本地线程分配缓冲,位于Eden区域中,每个线程都会有的一个独占区域,目的是为了在多线程情况下,避免发生线程安全的问题,当该空间满了之后通过同步的方式增加缓冲区大小

如果对你有帮助,点个赞,或者打个赏吧,嘿嘿
整理不易,请尊重博主的劳动成果

作者:Mango_SF
来源链接:https://www.cnblogs.com/Mango-Tree/p/12804088.html

版权声明:
1、JavaClub(https://www.javaclub.cn)以学习交流为目的,由作者投稿、网友推荐和小编整理收藏优秀的IT技术及相关内容,包括但不限于文字、图片、音频、视频、软件、程序等,其均来自互联网,本站不享有版权,版权归原作者所有。

2、本站提供的内容仅用于个人学习、研究或欣赏,以及其他非商业性或非盈利性用途,但同时应遵守著作权法及其他相关法律的规定,不得侵犯相关权利人及本网站的合法权利。
3、本网站内容原作者如不愿意在本网站刊登内容,请及时通知本站(javaclubcn@163.com),我们将第一时间核实后及时予以删除。


本文链接:https://www.javaclub.cn/java/68369.html

分享给朋友:

“JVM内存模型及内存分配” 的相关文章

【Java】JVM内存模型解析

【Java】JVM内存模型解析

   JVM内存模型主要分为五大区域:栈、堆、本地方法栈、程序计数器、方法区。   本地方法栈: 跟虚拟机栈非常相似,也是线程私有的,不过虚拟机栈是针对Java方法,而本地方法栈是针对native方法,也就是底层方...

jvm-java 内存模型  以及各个分区具体内容

jvm-java 内存模型 以及各个分区具体内容

java内存模型,这里其实是指 jvm运行时内存模型 1 每一个应用程序,都有一个JVM 而不是 多个应用程序,共享一个jvm 2 java源文件,首先通过编译器,把java语法的代码,编译成 jvm语法的字节码文件 这个过程,是不涉及到...

jvm中关于slot的理解

jvm中关于slot的理解

jvm中关于slot的理解 参数值的存放总是在局部变量数组的index0开始,到数组长度-1的索引结束。 局部变量表,最基本的存储单元是slot(变量槽) 局部变量表中存放编译期可知的各种基本数据类型(8种),引...

Java虚拟机5:Java垃圾回收(GC)机制详解

Java虚拟机5:Java垃圾回收(GC)机制详解

哪些内存需要回收? 哪些内存需要回收是垃圾回收机制第一个要考虑的问题,所谓“要回收的垃圾”无非就是那些不可能再被任何途径使用的对象。那么如何找到这些对象? 1、引用计数法 这个算法的实现是,给对象中添加一个引用计数器,每当一个地方引用这个对象时,计数器值+1;当引用失...

十、JVM常用启动参数

 一、JVM启动参数共分为三类:   1.其一是标准参数(-),所有的JVM实现都必须实现这些参数的功能,而且向后兼容;   2.其二是非标准参数(-X),指的是JVM底层的一些配置参数,这些参数在一般开发中默认即可,不需要任何配置。但是在生...

JVM-内存模型

JVM-内存模型

线程栈空间 包括程序计数器、虚拟机栈和本地方法栈 程序计数器 程序计数器是一块很小的内存空间,主要用来记录各个线程执行的字节码的地址,例如,分支、循环、跳转、异常、线程恢复等都依赖于计数器。由于 Java 是多线程语言,当执行的线程数量超过 CPU 核数时,线程之间会...

Jvm-Sandbox-Repeater架构

Jvm-Sandbox-Repeater架构

一、Repeater整体架构 1.1 Jvm-Sandbox-Repeater简介 Jvm-Sandbox-Repeater是一个基于Jvm-Sandbox的 服务端录制/回放 通用解决方案 1.1.1 服务端录制回放的概念...

jvm内存模型

jvm内存模型

今天接到阿里的电话面试,面试结果不理想,其中一个技术题目就是问我知道jvm内存模型。这个问题我没答好,现在做一些笔记在此。        ...

jvm(一)

jvm(一)

JVM与Java体系结构 前言 作为Java工程师的你曾被伤害过吗?你是否也遇到过这些问题? 运行着的线上系统突然卡死,系统无法访问,甚至直接OOMM! 想解决线上JVM GC问题,但却无从下手。 新项目上线,对各种...

【1】JVM-内存模型

【1】JVM-内存模型

本篇其实就是一个读书笔记,书是《深入理解JAVA虚拟机》,在网上搜索JAVA内存,说的比较好的其实很多都源自这本书,作为一个JAVA程序员,理解虚拟机是通向高级程序员的必经道路。本篇中的图片源自当时网上,具体出处找不到了,请见谅。  ...

发表评论

访客

◎欢迎参与讨论,请在这里发表您的看法和观点。