专栏首页洁癖是一只狗JVM内存模型详解

JVM内存模型详解

在Java中,JVM内存模型主要分为堆,方法区,程序计数器,虚拟机栈,本地方法栈,如下图

今天我们就分别讲解一下这几个区域的作用

堆是JVM内存中最大的一块内存,该内存是被多有线程共享,几乎所有的对象和数组都在堆上分配,堆被划分为新生代和老年代,新生代又分为Eden和Survivor区,最后Survivor分为From Survivor和To Survivor组成

java6中,永久代放在非堆内存去,java7把永久代的静态变量和运行时常量放在了堆中,java8永久代被元空间代替了,结构如下图

程序计数器

程序计数器是一块很小的内存空间,主要记录了线程的字节码资质,如分支,循环,跳转,异常,线程恢复等会依赖程序计数器

比如,在多线程中,当线程的数量多于CPU的数量的时候,线程之间就会发生CPU抢占,比如一个线程的时间片用完了,或者其他原因此线程的CPU资源被提前抢夺,那么这个线程退出就需要一个程序计数器记录下一次被唤醒的指令,且是唯一一个没有规定任何OutOfMemoryError情况的区域.

方法区

很多开发者都习惯将方法区成为永久代,但是这两者并不等价。

HotSpot虚拟机使用永久代实现方法区,但是在其他虚拟机中,例如Oracle的JRockit,IBM的J9就不存在永久代的说法,可以说,HotSpot虚拟机中,设计人员使用永久代实现JVM内存模型的方法区。

方法区是用来存储加载类的相关信息,包括类信息,运行时常量,字符串常量池,类信息包括类的版本,字段,方法,接口和父类信息

JVM在执行某个类的时候,必须经过加载,连接,初始化,而连接又分为验证,准备,解析三个阶段,在加载类的时候,JVM会先加载class文件,而在class文件中除了有类的版本,字段,方法和接口等描述信息,还有一项信息就是常量池,为常量池存放的是字面量和符号引用

  • 字面量就是字符串,基本类型的常量(final修饰的变量)
  • 符号应用则包括类和方法的权限定名,字段的名称和描述以及方法的名称和描述符

同时类加载到内存之后,JVM将class文件的常量池放到了运行时常量池,在解析阶段,JVM会把符号引用替换为直接引用

例如,类中的一个字符串常量在class文件中,存放在class文件常量池中,在类加载完之后,JVM把这个字符串常量放到了运行时常量池,而在解析阶段,会指定该字符串对象的索引值,运行时常量是共享的,所以class文件中常量池多个相同的字符串在运行时常量池只有一份.

运行池常量是方法区的一部分,运行时常量相对于class中的常量池有一个另外的特性,就是具备动态性,java语言并不要求常量一定在编译期才会产生,运行期间也可以将新的常量放入池中,比如我们使用String.intern().

方法区和堆一样是线程共享的,因此如两个线程同时访问方法区的同一个类信息,而这个类还没有装入JVM,那么只有一个线程允许加载他,另外一个等待

同时在java7中已经把静态变量和运行池常量放到了堆中,其他部分存储在JVM的非堆内存中,但是在java8版本,使用元空间替代了永久代,除了静态变量和运行时常量还放在堆中,其余在方法区的信息都迁移到了元空间,而元空间是本地内存.

为什么用元空间替换永久代

  1. 移除永久代是为了以后可以融合HotSpot JVM与JRockit VM做准备,因为JRockit没有永久代
  2. 永久代内存经常溢出,爆出异常java.lang.OutOfMemoryError: PermGen,这是因为java7指定永久代的大小是8M,而每次FULL GC的回收率偏低,不是很好,并且永久代的大小也依赖很多因素,如JVM加载的class总数,常量池的大小和方法的大小.

虚拟机栈

java虚拟机是线程私有的内存空间,他和java线程一起创建,和销毁,当一个线程创建的时候,会在虚拟机栈中申请一个线程栈,存放方法的局部变量,操作数栈,动态链接方法和返回地址等信息,并参与方法的调用和返回,每一个方法的调用伴随着入栈,调出伴随着出栈

本地方法栈

本地方法栈和虚拟机栈功能类似,但是他是管理本地方法的调用,java虚拟机用于管理java函数的调用,且本地方法栈是有c语言实现,而虚拟机栈是有java实现

本文分享自微信公众号 - 洁癖是一只狗(rookie-dog),作者:洁癖汪

原文出处及转载信息见文内详细说明,如有侵权,请联系 yunjia_community@tencent.com 删除。

原始发表时间:2021-01-08

本文参与腾讯云自媒体分享计划,欢迎正在阅读的你也加入,一起分享。

我来说两句

0 条评论
登录 后参与评论

相关文章

  • 基于JDK8的JVM内存模型详解与GC策略

    在JDK 8中,永久代被删除,类元数据在本机内存中分配。默认情况下,可用于类元数据的本机内存量是无限制的。使用该选项MaxMetaspaceSize可以为用于类...

    yingzi_code
  • 大数据开发:关于JVM内存模型JMM详解

    Java内存模型(Java Memory Model ,JMM)就是一种符合内存模型规范的,屏蔽了各种硬件和操作系统的访问差异的,保证了Java程序在各种平台下...

    成都加米谷大数据
  • 【图文详解系列】JVM 内存模型

    进程计数器PC,当前线程所执行的字节码行号指示器。每个线程都有自己计数器,是私有内存空间,该区域是整个内存中较小的一块。

    一个会写诗的程序员
  • 了解JVM内存模型

    如果想了解JVM内存模型,首先我们要知道JVM是什么?JVM全称 Java Virtual Machine ,即Java虚拟机,是用于运行Java程序编译后的字...

    烟雨星空
  • JVM内存模型

    java404
  • JVM内存模型

    先磨磨肩擦擦掌,小二很早就听说jvm的内存很是奇特,今日一看果然不同凡响。下面且听小二一一道来。

    shengjk1
  • JVM内存模型

    运行时数据区域 Java虚拟机(Java Virtual Machine,简称JVM)在执行Java程序的过程中会把它所管理的内存划分为若干个不同的数据区域。这...

    武培轩
  • jvm内存模型

    JVM定义了若干个程序执行期间使用的数据区域。这个区域里的一些数据在JVM启动的时候创建,在JVM退出的时候销毁。而其他的数据依赖于每一个线程,在线程创建时创...

    lyb-geek
  • JVM内存模型

    JVM定义了若干个程序执行期间使用的数据区域。这个区域里的一些数据在JVM启动的时候创建,在JVM退出的时候销毁。而其他的数据依赖于每一个线程,在线程创建时创建...

    黑洞代码
  • JVM内存模型

    入门小站
  • JVM内存模型

    前一段时间写过一篇关于 JVM虚拟机之类加载的过程 的文章,其中讲述了Java虚拟机对类的处理。最近听了一次部门内部有关JVM的分享,自己也顺便回顾了之前阅读《...

    静默加载
  • jvm(1):jvm内存模型

    身为一个职业的Java程序员,每天打交到最多的就是jvm,那么套用孙子的一句话“知己知彼方能百战不殆”,熟悉jvm也就意味着是我们进阶路上必过之槛,下面先来张图...

    yiduwangkai
  • 深入理解JVM(一)——JVM内存模型

    JVM内存模型 Java虚拟机(Java Virtual Machine=JVM)的内存空间分为五个部分,分别是: 1. 程序计数器 2. Java虚...

    大闲人柴毛毛
  • JVM初探 -JVM内存模型

    Tanyboye
  • JVM初探 -JVM内存模型

    Java GC(Garbage Collection,垃圾收集,垃圾回收)机制,是Java与C++/C的主要区别之一,作为Java开发者,一般不需要专门编写内存...

    哲洛不闹
  • Jvm内存模型深度理解

    之前是对jvm内存模型一知半解,本次打算抽时间认认真真的理解一遍jvm内存模型,在这个过程中遇到了好多问题,针对这些问题查询资料再加上自己的理解对jvm内存模型...

    XING辋
  • 2.1 jvm内存模型

    Description of Java Conceptual Diagram(java结构)

    用户7798898
  • JVM|02内存模型

    Java内存模型(Java Memory Model ,JMM)就是一种符合内存模型规范的,屏蔽了各种硬件和操作系统的访问差异的,保证了Java程序在各种平台下...

    微笑的小小刀
  • Java 内存模型详解

    Java的内存模型(Java Memory Model )简称JMM。首先应该明白,Java内存模型是一个规范,主要规定了以下两点:

    乱敲代码

扫码关注云+社区

领取腾讯云代金券