来自:会点代码的大叔

JVM 运行时数据区域大致可以分为:程序计数器、虚拟机栈、本地方法栈、堆区、元空间、运行时常量池、直接内存等区域;就是下面这个样子的:

其中有些区域,随着 JDK 版本的升级不断调整,例如:

  • JDK 1.6,字符串常量池位于永久代的运行时常量池中;

  • JDK 1.7,字符串常量池从永久代剥离,放入了堆中;

  • JDK 1.8,元空间取代了永久代,并且放入了本地内存(Native memory)中。

以上几个区域,按照线程公有还是私有可分为:

  • 线程隔离:程序计数器、虚拟机栈、本地方法栈;

  • 线程公有:其它的都是线程共享的区域。

让我们主要讲解下每一个区域都是做什么用的,以及为什么它是隔离或公有的。

01

线程私有

1. 程序计数器

一个 CPU 在某个时间点,只能做一件事情,在多线程的情况下,CPU 运行时间被划分成若干个时间片,分配给各个线程执行;

程序计数器的作用就是记录当前线程执行的位置,当线程被切换回来的时候,能够找到该线程上次运行到哪儿了;所以程序计数器一定是线程隔离的。

2. 虚拟机栈和本地方法栈

  • 虚拟机栈:每个 Java 方法在执行的同时,会创建一个栈帧,用于存储局部变量表、操作数栈、常量池引用等信息;方法的调用过程,就是一个栈帧在 Java 虚拟机栈中入栈和出栈的过程;

  • 本地方法栈:和虚拟机栈很类似,区别在于虚拟机栈为 Java 方法服务,本地方法栈为 Native 方法服务;其中 Native 方法可以看做用其它语言(C、C++ 或汇编语言等)编写的方法;

  • HotSpot 虚拟机就选择了将虚拟机栈和本地方法栈合并在了一起;

为了保证线程中的局部变量不被别的线程访问到,所以虚拟机栈和本地方法栈是线程隔离的。

02

线程公有

1. 堆区 

对于堆栈的区别总结一句话:堆中存对象,栈中存基本数据类型和堆中对象的引用;一个对象的大小是可以动态变化的,而引用是固定大小的。

这么看就容易理解堆为什么是线程公有的了,省地儿啊。

2. 元空间区/方法区 

方法区用于存放已被加载的类信息、常量、静态变量、即编译器编译后的代码等。

还有要注意的一点:方法区是 JVM 的规范,在 JDK 1.8 之前,方法区的实现是永久代;从 JDK 1.8 开始 JVM 移除了永久代,使用本地内存来存储元数据并称之为:元空间(Metaspace)。

3. 运行时常量池 

Class 文件中的常量池,会在类加载后被放入这个区域。

另外在 JDK 1.7 之前,字符串常量池就在运行时常量池中,后来字符串常量池放入了堆中,而运行时常量池仍然在方法区(元空间区)中。

有兴趣的朋友可以自己测试一下,以死循环方式创建字符串常量,在 JDK 1.6 里会报永久代 OOM ;在 JDK 1.7 里会报堆区 OOM 。

4. 直接内存 

也叫做堆外内存,并不是虚拟机运行时数据区的一部分,也不是Java 虚拟机规范中定义的内存区域。

JDK 1.4 加入的 NIO 类,引入了一种基于通道 ( Channel ) 与缓冲区 ( Buffer ) 的 I/O 方式,它可以使用 native 函数库直接分配堆外内存,然后通过堆上的DirectByteBuffer对象对这块内存进行引用和操作。

简单来说,直接内存就是 JVM 内存之外有一块内存区域,我们通过堆上的一个对象可以操作它;具体等讲到 NIO 部分的时候,再回来加深理解。

长按订阅更多精彩▼

如有收获,点个在看,诚挚感谢

Java 运行时数据区域,哪些是线程隔离的?哪些又是公有的?相关推荐

  1. Java 运行时数据区域

    运行时数据区域 Java 虚拟机在执行 Java 程序的过程中会把它所管理的内存划分为若干个不同的数据区域.这些区域都有各自的用途,以及创建和销毁时间.以下是 Java 虚拟机所管理的内存区域: 程序 ...

  2. JVM学习笔记:Java运行时数据区域

    JVM执行Java程序的过程中,会使用到各种数据区域,这些区域有各自的用途.创建和销毁时间.根据<Java虚拟机规范>,JVM包括下列几个运行时数据区域,如下图所示: 其中红色部分是线程私 ...

  3. Java运行时数据区域

    一.java的运行时数据区域 Java虚拟机在执行Java程序的过程中会把它所管理的内存划分为若干个不同的数据区域.这些区域都有各自的用途,以及创建和销毁的时间,有的区域随着虚拟机进程的启动而存在,有 ...

  4. [JVM-1]Java运行时数据区域

    Java虚拟机(JVM)内部定义了程序在运行时需要使用到的内存区域 这些区域都有自己的用途,以及创建和销毁的时间.有些区域随着虚拟机进程的启动而存在,有的区域则依赖用户线程的启动和结束而销毁和建立. ...

  5. 1-JVM之Java运行时数据区域

    程序计数器 作用: 程序计数器是较小的内存空间,它可以当做是当前线程所执行的字节码的行号指示器. 字节码解释器工作时就是通过改变这个计数器的值来选取下一条需要执行的字节码指令,分支,循环,跳转,异常处 ...

  6. Java内存区域(运行时数据区域)和内存模型(JMM)

    原文作者:czwbig 原文:https://www.cnblogs.com/czwbig/p/11127124.html Java 内存区域和内存模型是不一样的东西,内存区域是指 Jvm 运行时将数 ...

  7. JDK1.8-Java虚拟机运行时数据区域和HotSpot虚拟机的内存模型

    2019独角兽企业重金招聘Python工程师标准>>> 官方文档规定的运行时数据区域 官方文档中规定的运行时数据区一共就几块: PC计数器, 虚拟机栈, 本地方法栈, 堆区, 方法区 ...

  8. 12.JDK1.8 JVM运行时数据区域概览、各区域介绍、程序计数器、Java虚拟机栈、本地方法栈、堆、堆空间内存分配(默认情况下)、字符串常量池、元数据区、jvm参数配置

    12.JDK1.8 JVM运行时数据区域概览 12.1.JDK1.8 JVM运行时数据区域概览 12.2.各区域介绍 12.3.各区域介绍 12.3.1.程序计数器 12.3.2.Java虚拟机栈 1 ...

  9. java虚拟机之一内存运行时数据区域解释

    Java虚拟机管理的内存运行时数据区域解释 Java虚拟机在执行Java程序的过程中会把它所管理的内存划分为若干个不同数据区域.这些区域都有各自的用途,以及创建和销毁的时间,有的区域随着虚拟机进程的启 ...

最新文章

  1. c#listView
  2. tensorflow使用tf.placeholder会报错
  3. C#上位机软件串口数据接收用Invoke(同步)和BeginInvoke(异步)的区别
  4. linux把用户添加到组
  5. Ubuntu 20.10安装docker
  6. dba 权限_DBA如何玩转PG用户、角色和权限管理?
  7. java21天打卡day20-集合
  8. 关于空间复杂度,你可能有几个疑问?
  9. hdu 4781 Beautiful Soup 构造
  10. int main ( int argc, char** argv )的说明
  11. vuejs 开发中踩到的坑
  12. 什么是项目工作说明书?
  13. 越有钱越抠门 李嘉诚西装一穿就是十年
  14. 深度学习的发展背景和历史
  15. 多项式拟合(polyfit)及局部加权回归(Lowess)对二维数据基础规律和离群特征学习的分析对比
  16. android声音录制音量太小,为什么总是感觉手机音量太小?跟我这样设置,声音瞬间大上许多...
  17. cad安装日志文件发生错误_CAD因为发生错误安装过早结束 致命错误解决方法
  18. 微软重申人工智能将增强人类体验而不是取而代之
  19. 程序员-开发工作流程英文术语
  20. ssl简介-加密算法

热门文章

  1. HDU5934(强连通分量)
  2. 封装成vla函数_不知道怎么封装代码?看看这几种设计模式吧!
  3. AtCoder Beginner Contest 202 D - aab aba baa(组合计数,字典序)
  4. linux 0.01内核分析与操作系统设计 pdf,《Linux 0.01内核分析与操作系统设计——创造你自己的操作系统》...
  5. python3基础知识点_入门Python3基础教程-知识点摘要
  6. C++ name mangling
  7. Mysql中分页查询两个方法比较
  8. Java网络编程——11.非阻塞I/O
  9. 第三章GIT使用入门
  10. scala class和object,trait的区别