前言

上篇文章我们一起了解了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. 4GL之Non-SCROLLING CURSOR

    在4gl中CURSOR可以说是每一个程序中都会有的,而CURSOR又分为三种SCROLLING CURSOR.Non-SCROLLING CURSOR.LOCKING CURSOR. Non-SCRO ...

  2. Ambari 邮件监控服务

    配置邮箱授权码 这里演示的是网易邮箱 开启SMTP服务 配置邮件模板 • 下载警告邮件模板 wget https://raw.githubusercontent.com/apache/ambari/b ...

  3. 报错:ER_NO_DEFAULT_FOR_FIELD: Field 'status' doesn't have a default value

    小白入门级错误,数据库插入数据时报错;ER_NO_DEFAULT_FOR_FIELD: Field 'status' doesn't have a default value  百度说是my.ini文 ...

  4. 手写迷你Tomcat

    手写迷你Tomcat手写迷你Tomcat手写迷你Tomcat手写迷你Tomcat手写迷你Tomcat手写迷你Tomcat手写迷你Tomcat手写迷你Tomcat手写迷你Tomcat手写迷你Tomcat ...

  5. PostgreSQL在不同的表空间移动数据文件

    一.背景 在工作中,可能会遇到将表从一个表空间移动另一个表空间.例如 * 对数据进行冷处理 * 表空间所在的磁盘空间不足 * 建表时分配错了表空间 以上等等,可能需要你将一个表移动表空间. 二.表空间 ...

  6. Android Studio从Eclipse导项目

    要是你只下了Android Studio 就不能用Eclipse导出gradle项目了 可以直接使用Android Studio导入模块,在Android Studio里Project算Eclipse ...

  7. lidar激光雷达领域的分类

    lidar领域可以按分为以下五方面: 激光雷达系统与装备 激光雷达系统与开发 激光雷达光源 激光雷达探测 多光谱激光雷达系统 单光子激光雷达系统 低成本RGB-D距离传感器 激光雷达元器件及装备等 激 ...

  8. Codeforces 1321D Navigation System

    题意 有个人要从\(s\)走到\(t\),经过的路径给定.导航系统每次会显示当前节点到\(t\)的最短路,有多条就显示其中之一.这个人如果按照导航走,那么啥都没变.如果没有按导航走导航就会重新导航.问 ...

  9. 如何利用 docker 快速部署 Mysql 服务

    docker 基础教程不再多说,这里只着重讲如何使用 docker 部署 mysql 服务 docker 拉取 访问 dockerhub,搜索关键词 mysql,我这里选择 mysql-server, ...

  10. 一文读懂神经网络训练中的Batch Size,Epoch,Iteration

    一文读懂神经网络训练中的Batch Size,Epoch,Iteration 作为在各种神经网络训练时都无法避免的几个名词,本文将全面解析他们的含义和关系. 1. Batch Size 释义:批大小, ...