JVM内存模型不再是秘密
前言
上篇文章我们一起了解了jvm虚拟机类的加载机制,而且是以一种纯大白话进行的一场闲聊,相信小伙伴们应该印象深刻,感兴趣的小伙伴可以重温一下上一篇文章大白话谈JVM的类加载机制。
当jvm加载了类后,会把需要使用的对象放入到内存当中,那么jvm的内存模型是什么样的呢?
今天我们就来探索一下jvm的内存模型。由于有小伙伴反映想加些图更容易理解,王子接下来的文章打算用更多的图例来讲解。
方法区
很多小伙伴之前也了解过jvm的内存模型,知道有方法区这个东西,但可能了解的不是很详细。
其实方法区是在JDK1.8以前的版本里存在的一块内存区域,主要就是存放从class文件里加载进来的类的,而且常量池也是在这块区域内的。
但是在JDK1.8之后,这块区域摇身一变,换了名字,叫做“Metaspace”,翻译过来就是“元数据空间”的意思。当然它只是改了个名,实现的功能是没变的。

程序计数器
假设我们的代码是这样的:
public class Main {
public static void main(String[] args) {
SysUser sysUser = new SysUser();
sysUser.setAvatar("1");
}
}
这个是我们的java代码,是面向我们开发者的,然后会编译成class字节码文件,在class字节码文件中存放的是一条条的字节码命令,他对应了一条条的机器指令,计算机只有读到机器指令才知道它要干什么。
所以当JVM加载类信息后,实际上就是使用字节码执行引擎去执行我们的代码编译出来的一条条字节码指令,如下图。

那么在执行字节码指令的时候,jvm是怎么知道该执行哪条指令了呢?这时候程序计数器就出现了。
它就是用来记录当前执行的字节码指令位置的。

另外,小伙伴们都知道,JVM是支持多线程的,所以如果我们开启了多线程,就会有多个线程在执行不同的字节码指令,为了他们之间的字节码指令不会混在一起,所以每个线程都会有自己的程序计数器,用来记录每个线程自己的指令现在执行到哪一条了,如下图:

JAVA虚拟机栈
我们现在知道,jvm执行class中指令时是通过程序计数器来锁定执行的指令位置的,但是在我们执行的方法里,会有很多的局部变量等数据,虚拟机栈就是用来保存方法的局部变量的,而且每个线程都会有自己的虚拟机栈,比如我们之前的代码:
public class Main {
public static void main(String[] args) {
SysUser sysUser = new SysUser();
sysUser.setAvatar("1");
}
}
这个代码会启动一个main线程,并把局部变量sysUser保存到栈中。
如果线程执行了一个方法,就会对这个方法调用创建一个栈帧,然后就是所谓的压栈操作(先进后出),如下:

然后我们代码继续执行,调用了setAvatar方法,那么就会继续创建栈帧,如下:

当setAcatar方法执行完毕,就会对方法的栈帧执行出栈操作。
以上就是JAVA虚拟机栈这一部分的作用,简单概括就是:调用方法就创建栈帧,压栈,方法执行完就执行出栈操作。
JAVA堆内存
说完了java虚拟机栈,那我们再来说一个很重要的内存区域java堆内存,它是用来存放我们代码中创建的各种对象的。
还是以刚才的代码为例,当我们执行new SysUser()的时候,就创建了一个SysUser实例对象,而这个对象本身又会有很多的属性和方法,这样的实例化对象的数据就是存放在堆内存中的。
而这个时候我们在栈中存储的局部变量实际上存的就是这个对象的内存地址,也可以理解为一个引用地址。如下图:

到这里JVM的内存区域已经和小伙伴们介绍完了,给大家来一张整体的内存区域图,以便理解:

其他内存区域
除了前文我们介绍的内存区域,jdk的api中(io、nio、socket)相关,其实它们的内部已经不是java代码了,而是调用了native方法调用了本地操作系统的一些方法,可能是c语言编写的或者是一些底层类库。
在调用native方法的时候,线程就会对应本地方法栈,这个是于java虚拟机栈类似的东东,放的就是native方法的各种局部变量表。
除此之外还有一个区域,是不属于JVM的,通过NIO的allocateDirect的api,可以在堆外分配内存空间,从而直接操作堆外的内存空间数据。
有些场景下,堆外内存空间会提升性能,这个问题我们之后再逐步探索,今天就不说这个了。
总结
本文到这里就结束啦,王子采纳了一些小伙伴的意见,画了很多图有助于小伙伴们更好的理解,希望能够帮到大家。
那我们下篇文章见。
往期文章推荐:

JVM内存模型不再是秘密的更多相关文章
- JVM内存模型和性能优化 转
JVM内存模型和性能优化 JVM内存模型优点 内置基于内存的并发模型: 多线程机制 同步锁Synchronization 大量线程安全型库包支持 基于内存的并发机制,粒度灵活控制,灵活度高于 ...
- jvm内存模型-回收算法-和内存分配以及jdk、jre、jvm是什么关系(阿里,美团,京东面试题)
1.什么是jvm?(1)jvm是一种用于计算设备的规范,它是一个虚构出来的机器,是通过在实际的计算机上仿真模拟各种功能实现的.(2)jvm包含一套字节码指令集,一组寄存器,一个栈,一个垃圾回收堆和一个 ...
- Inside JVM 内存模型
Inside JVM 内存模型 来源 原文:https://blog.csdn.net/silentbalanceyh/article/details/4661230 参考:IBM开发中心文档,&l ...
- [转]JVM内存模型
最近排查一个线上java服务常驻内存异常高的问题,大概现象是:java堆Xmx配置了8G,但运行一段时间后常驻内存RES从5G逐渐增长到13G #补图#,导致机器开始swap从而服务整体变慢.由于Xm ...
- 如何从编程的本质理解JVM内存模型
如何从编程的本质理解JVM内存模型 一般聊JVM内存模型都是把图截出来,然后对着图,解释上面堆.栈之类的概念.这篇将分享下,如何从编程的本质上理解,JVM内存模型是什么样子,为什么是这个样子,不再死记 ...
- 程序猿的日常——JVM内存模型与垃圾回收
Java开发有个很基础的问题,虽然我们平时接触的不多,但是了解它却成为Java开发的必备基础--这就是JVM.在C++中我们需要手动申请内存然后释放内存,否则就会出现对象已经不再使用内存却仍被占用的情 ...
- JVM内存模型和垃圾回收
Java开发有个很基础的问题,虽然我们平时接触的不多,但是了解它却成为Java开发的必备基础——这就是JVM.在C++中我们需要手动申请内存然后释放内存,否则就会出现对象已经不再使用内存却仍被占用的情 ...
- JVM内存模型 三
本文章节: 1.JMM简介 2.堆和栈 3.本机内存 4.防止内存泄漏 1.JMM简介 i.内存模型概述 Java平台自动集成了线程以及多处理器技术,这种集成程度比Java以前诞生的计算机语言要厉 ...
- 【Java_基础】JVM内存模型与垃圾回收机制
1. JVM内存模型 Java虚拟机在程序执行过程会把jvm的内存分为若干个不同的数据区域来管理,这些区域有自己的用途,以及创建和销毁时间. JVM内存模型如下图所示 1.1 程序计数器 程序计数器( ...
随机推荐
- 在Unity中检测死循环和卡死
当游戏在手机/模拟器上卡死,logcat没有日志输出,也没有卡死堆栈信息或者bugly也没有捕获到异常,你是否很焦急?本文介绍一下我们项目中检测Unity卡死的方法,也许适合你使用. 实现原理 在绝大 ...
- 消息型中间件之RabbitMQ集群
在上一篇博客中我们简单的介绍了下rabbitmq简介,安装配置相关指令的说明以及rabbitmqctl的相关子命令的说明:回顾请参考https://www.cnblogs.com/qiuhom-187 ...
- 网站seo整站优化有什么优势
http://www.wocaoseo.com/thread-314-1-1.html 现在很多企业找网络公司做网站优化,已经不再像以前那样做目标关键词,而是通过整站优化来达到企业营销目的 ...
- SpringBoot2搭建基础架构——开源软件诞生4
技术框架篇--第4篇 用日志记录“开源软件”的诞生 赤龙ERP开源地址: 点亮星标,感谢支持,加微信与开发者交流 kzca2000 码云:https://gitee.com/redragon/redr ...
- Java集合 Collection、Set、Map、泛型 简要笔记
集合 什么是集合 概念 对象的容器,实现了对对象常用的操作 和数组的区别 数组长度固定,集合长度不固定 数组可以存储基本类型和引用类型,集合只能存储引用类型 位置 java.util.*; Colle ...
- 你可能不了解的java枚举
枚举在java里也算个老生长谈的内容了,每当遇到一组需要类举的数据时我们都会自然而然地使用枚举类型: public enum Color { RED, GREEN, BLUE, YELLOW; pub ...
- 数据结构与算法系列2 线性表 链表的分类+使用java实现链表+链表源码详解
数据结构与算法系列2.2 线性表 什么是链表? 链表是一种物理存储单元上非连续,非顺序的存储结构,数据元素的逻辑顺序是通过链表的链接次序实现的一系列节点组成,节点可以在运行时动态生成,每个节点包括两个 ...
- Labview学习之路(八)如何让控件显示在修饰符的前面
在Labview2017版本中,前面板选择修饰控件,会出现部分修饰控件会掩盖其他控件,情况如下: 我们右键点击和属性中都没有相关属性的改变,为什么是这样我也不清除: 上网查了一下,看到其他版本会有显示 ...
- Python 中的数字到底是什么?
花下猫语:在 Python 中,不同类型的数字可以直接做算术运算,并不需要作显式的类型转换.但是,它的"隐式类型转换"可能跟其它语言不同,因为 Python 中的数字是一种特殊的对 ...
- JSON<前后端的沟通>
1.什么是JSON ==>1什么是json json:是一种轻量级数据交互格式 数据交互:每一种语言的编码都不一样,他们之间互不认识.但是现在的情况是不同的语言开发出的系统也需要进行数据交互,这 ...