前言

上篇文章我们一起了解了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内存模型不再是秘密的更多相关文章

  1. JVM内存模型和性能优化 转

    JVM内存模型和性能优化 JVM内存模型优点 内置基于内存的并发模型:      多线程机制 同步锁Synchronization 大量线程安全型库包支持 基于内存的并发机制,粒度灵活控制,灵活度高于 ...

  2. jvm内存模型-回收算法-和内存分配以及jdk、jre、jvm是什么关系(阿里,美团,京东面试题)

    1.什么是jvm?(1)jvm是一种用于计算设备的规范,它是一个虚构出来的机器,是通过在实际的计算机上仿真模拟各种功能实现的.(2)jvm包含一套字节码指令集,一组寄存器,一个栈,一个垃圾回收堆和一个 ...

  3. Inside JVM 内存模型

    Inside JVM 内存模型 来源  原文:https://blog.csdn.net/silentbalanceyh/article/details/4661230 参考:IBM开发中心文档,&l ...

  4. [转]JVM内存模型

    最近排查一个线上java服务常驻内存异常高的问题,大概现象是:java堆Xmx配置了8G,但运行一段时间后常驻内存RES从5G逐渐增长到13G #补图#,导致机器开始swap从而服务整体变慢.由于Xm ...

  5. 如何从编程的本质理解JVM内存模型

    如何从编程的本质理解JVM内存模型 一般聊JVM内存模型都是把图截出来,然后对着图,解释上面堆.栈之类的概念.这篇将分享下,如何从编程的本质上理解,JVM内存模型是什么样子,为什么是这个样子,不再死记 ...

  6. 程序猿的日常——JVM内存模型与垃圾回收

    Java开发有个很基础的问题,虽然我们平时接触的不多,但是了解它却成为Java开发的必备基础--这就是JVM.在C++中我们需要手动申请内存然后释放内存,否则就会出现对象已经不再使用内存却仍被占用的情 ...

  7. JVM内存模型和垃圾回收

    Java开发有个很基础的问题,虽然我们平时接触的不多,但是了解它却成为Java开发的必备基础——这就是JVM.在C++中我们需要手动申请内存然后释放内存,否则就会出现对象已经不再使用内存却仍被占用的情 ...

  8. JVM内存模型 三

    本文章节: 1.JMM简介 2.堆和栈 3.本机内存 4.防止内存泄漏   1.JMM简介 i.内存模型概述 Java平台自动集成了线程以及多处理器技术,这种集成程度比Java以前诞生的计算机语言要厉 ...

  9. 【Java_基础】JVM内存模型与垃圾回收机制

    1. JVM内存模型 Java虚拟机在程序执行过程会把jvm的内存分为若干个不同的数据区域来管理,这些区域有自己的用途,以及创建和销毁时间. JVM内存模型如下图所示 1.1 程序计数器 程序计数器( ...

随机推荐

  1. 系综的实现方式(nve、nvt、npt)

    一.NVE系综 更新位置和速度,v和e恒定. 二.NVT系综 几种实现的方式: 如: fix 1 all nve #更新位置和速度,e和V保持不变.若只有这个命令,就只nve系综,如果和控温命令一起, ...

  2. Http请求-okhttp3基本用法

    简介 HTTP是现代应用常用的一种交换数据和媒体的网络方式,高效地使用HTTP能让资源加载更快,节省带宽.OkHttp是一个高效的HTTP客户端,它有以下默认特性: 支持HTTP/2,允许所有同一个主 ...

  3. Ant Design Vue使用支持v-model效验的FormModel表单遇到的一个坑

    按照官网上用法写好表单后,在a-select上绑定了change事件 <a-form-model-item label="类型" prop="config.type ...

  4. shell脚本同步私人git仓库

    前言 分别在个人电脑.个人服务器.码云三个地方建立了数据仓库用于保存自己的各种数据,通过git+shell进行数据同步. 此举不仅可以避免因存储损坏.版本更迭.数据误操作等因素带来的各种麻烦,也能实现 ...

  5. 社区布道师揭秘消息中间件技术内幕,撰写MQ架构设计与实现原理

    RocketMQ是什么 RocketMQ是由阿里捐赠给Apache的一款分布式.队列模型的开源消息中间件,经历了淘宝双十一的洗礼. RocketMQ的特性 RocketMQ基本概念 Client端 P ...

  6. java里equals和hashCode之间什么关系

    如果要比较实际内存中的内容,那就要用equals方法,但是!!! 如果是你自己定义的一个类,比较自定义类用equals和==是一样的,都是比较句柄地址,因为自定义的类是继承于object,而objec ...

  7. windows下安装jdk+tomcat+maven并配置

    一.下载安装jdk并配置 1.1 进行JDK下载 下载地址:一键直达 一般下载后,安装位置默认,一路下一步,一直到安装完毕-"关闭". 1.2 环境变量配置 不要管是不是一般情况, ...

  8. vue 中使用echarts

    前言:在vue2.0中使用百度echarts有三种解决方案. 一.原始方法直接使用 这样每次都要获取图表dom元素 然后通过setOption渲染数据,最后在mounted中初始化.很麻烦. < ...

  9. Kubernetes-14:一文详解Pod、Node调度规则(亲和性、污点、容忍、固定节点)

    Kubernetes Pod调度说明 简介 Scheduler 是 Kubernetes 的调度器,主要任务是把定义的Pod分配到集群的节点上,听起来非常简单,但要考虑需要方面的问题: 公平:如何保证 ...

  10. Vue企业级优雅实战03-准备工作04-全局设置

    本文包括如下几个部分: 初始化环境变量文件 JS 配置文件初始化:如是否开启 Mock 数据.加载本地菜单.URL 请求路径等: 国际化文件初始化:初始化国际化文件的结构: 整合 Element UI ...