5分钟带你了解JVM的内存分配

前言

JVM的内存分配是一个老生常谈的话题了,但是如果开发者想要开发出高质量的APP,那么JVM的内存分配是必须要了解的。本文主要介绍JVM的内存分配。

推荐

文章发布将优先在个人博客「李益的小站」与微信公众号「Code满满」发布,快来关注吧!

JVM的内存区域划分

在网上一些介绍JVM内存分配的文章中,他们将Java的内存大致分为堆内存(heap)和栈内存(stack),这种划分的方式,体现了开发者最关注的区域,但是并不完全准确。JVM会将内存划分为若干个不同的数据区域,主要分为:程序计数器虚拟机栈本地方法栈方法区这五部分。

在介绍这五个内存区域前,我们先了解一下,Java文件被JVM加载到内存中的过程:

  1. A.java文件经过编译器编译,生成A.class字节码文件
  2. 程序访问A这个类时,会通过ClassLoader(类加载器)将A.class加载到JVM的内存中
  3. JVM将内存区域划分为若干个不同的数据区域,主要分为:程序计数器虚拟机栈本地方法栈方法区这五部分。
    JVM内存分布

程序计数器

程序计数器的作用

Java程序是多线程的,线程的执行与挂起由CPU来决定。当CPU将一个线程(暂且就叫A线程)挂起,去执行另一线程(暂且叫B线程)时,这时需要记录代码已经执行到的位置;当CPU重新执行A线程时,就可以根据之前记录的位置,知道自己应该从哪行代码开始继续执行下去。这就是程序计数器的作用,程序计数器是虚拟机中一块比较小的内存空间,主要用于记录当前线程执行的位置。

当然,除了上述的线程的恢复操作之外,还有一些其他操作也依赖程序计数器来完成,比如:跳转、异常处理等

程序计数器的几个注意点:

  1. 程序计数器是线程私有的,每条线程内部都有一个私有的程序计数器。它的生命周期随着线程创建而创建,随着线程的结束而结束
  2. 在JVM规范中,对程序计数器这一区域没有规定任何的OutOfMemoryError的情况
  3. 当一个线程正在执行一个Java方法的时候,程序计数器记录的是正在执行的虚拟机字节码指令的地址。如果正在执行的是Native方法,则计数器的值为空

虚拟机栈

虚拟机栈也是线程私有的,与线程的生命周期同步。我们常听说的 “JVM是基于栈的解释器执行的,DVM是基于寄存器的解释器执行的” 这句话中,“基于栈”就指的是虚拟机栈。每当有方法被执行时,JVM都会在虚拟机栈中创建一个栈帧。而这这个栈帧是用于支持虚拟机进行方法调用和方法执行的数据结构。每当一个线程在执行某个方法时,都会为这个方法创建一个栈帧(所以一个线程中可以有多个栈帧)。所以虚拟机栈其实就是用来描述Java方法执行的内存模型。


栈帧结构

栈帧的结构

这里我们暂时就简单了解一下栈帧的结构。

  • 局部变量表(Local Variable Table)
    局部变量表一组变量值存储空间,用于存放方法参数和方法内部定义的局部变量。在Java文件编译为Class文件时,就在方法的Code属性的max_locals数据项中确定了该方法所需要分配的局部变量表的最大容量。

  • 操作数栈(Operand Stack)
    操作数栈也常称为操作栈,它是一个后入先出栈。同局部变量表一样,操作数栈的最大深度也在编译的时候写入到Code属性的max_stacks数据项中。操作数栈的每一个元素可以是任意的Java数据类型,包括long和double。

    当一个方法刚刚开始执行的时候,这个方法的操作数栈是空的。在方法的执行过程中,会有各种字节码指令往操作数栈中写入和提取内容,也就是出栈/入栈操作。

  • 动态链接
    class文件的常量池中存有大量的符号引用,字节码中的方法调用指令就以常量池中指向方法的符号引用作为参数。这些符号引用一部分会在类加载阶段或者第一次使用的时候就转化为直接引用,这种转化称为静态解析。另外一部分符号引用将在每一次运行期间转化为直接引用,这部分称为动态连接。

    虚拟机栈中,每个栈帧都包含一个指向运行时常量池中该栈帧所属方法的引用,持有这个引用是为了支持方法调用过程中的动态连接。

  • 方法返回地址
    当一个方法开始执行后,只有两种方式可以退出这个方法:

    • 正常退出:指方法中的代码正常完成,或者遇到任意一个方法返回的字节码指令(如return)并退出,没有抛出任何异常。
    • 异常退出:指方法执行过程中遇到异常,并且这个异常在方法体内内部没有得到处理,导致方法退出

    无论当前方法以哪种方式退出,在方法退出后都需要返回到方法被调用的位置,程序才能继续执行。而虚拟机栈中的“返回地址”就是用来帮助当前方法恢复他的上层方法执行状态。

虚拟机栈的几个注意点:

在JVM规范中,对虚拟机栈规定了两种异常状况:

  1. StackOverflowError:当线程请求栈深超出JVM所允许的最大深度时抛出
  2. OutOfMemoryError:当JVM动态扩展到无法申请足够内存时抛出

本地方法栈

本地方法栈和虚拟机栈基本相同,只不过是针对本地(Native)方法。有些虚拟机的实现中已经把两者合二为一了(比如HotSpot)

堆(Heap)是JVM所管理的内存区域中最大的一块,该区域唯一的目的就是存放对象实例,几乎所有对象的实例都在堆里分配,因此它也是Java垃圾收集器(GC)管理的主要区域。同时它也是所有线程共享的内存区域,因此被分配在区域的对象如果被多个线程访问,需要考虑线程安全问题。

而按照对象存储时间的不同,堆中的内存可以划分为新生代和年老代。其中新生代又被划分为Eden区和Survivor区。

堆内存分布

方法区

方法区是JVM规范里规定的一块运行时数据区。方法区主要是存储已经被JVM加载的类信息(版本、字段、方法、接口)、常量、静态变量、即时编译器编译后的代码与数据。方法区也是被各个线程共享的区域。

最后编辑于
©著作权归作者所有,转载或内容合作请联系作者
  • 序言:七十年代末,一起剥皮案震惊了整个滨河市,随后出现的几起案子,更是在滨河造成了极大的恐慌,老刑警刘岩,带你破解...
    沈念sama阅读 214,922评论 6 497
  • 序言:滨河连续发生了三起死亡事件,死亡现场离奇诡异,居然都是意外死亡,警方通过查阅死者的电脑和手机,发现死者居然都...
    沈念sama阅读 91,591评论 3 389
  • 文/潘晓璐 我一进店门,熙熙楼的掌柜王于贵愁眉苦脸地迎上来,“玉大人,你说我怎么就摊上这事。” “怎么了?”我有些...
    开封第一讲书人阅读 160,546评论 0 350
  • 文/不坏的土叔 我叫张陵,是天一观的道长。 经常有香客问我,道长,这世上最难降的妖魔是什么? 我笑而不...
    开封第一讲书人阅读 57,467评论 1 288
  • 正文 为了忘掉前任,我火速办了婚礼,结果婚礼上,老公的妹妹穿的比我还像新娘。我一直安慰自己,他们只是感情好,可当我...
    茶点故事阅读 66,553评论 6 386
  • 文/花漫 我一把揭开白布。 她就那样静静地躺着,像睡着了一般。 火红的嫁衣衬着肌肤如雪。 梳的纹丝不乱的头发上,一...
    开封第一讲书人阅读 50,580评论 1 293
  • 那天,我揣着相机与录音,去河边找鬼。 笑死,一个胖子当着我的面吹牛,可吹牛的内容都是我干的。 我是一名探鬼主播,决...
    沈念sama阅读 39,588评论 3 414
  • 文/苍兰香墨 我猛地睁开眼,长吁一口气:“原来是场噩梦啊……” “哼!你这毒妇竟也来了?” 一声冷哼从身侧响起,我...
    开封第一讲书人阅读 38,334评论 0 270
  • 序言:老挝万荣一对情侣失踪,失踪者是张志新(化名)和其女友刘颖,没想到半个月后,有当地人在树林里发现了一具尸体,经...
    沈念sama阅读 44,780评论 1 307
  • 正文 独居荒郊野岭守林人离奇死亡,尸身上长有42处带血的脓包…… 初始之章·张勋 以下内容为张勋视角 年9月15日...
    茶点故事阅读 37,092评论 2 330
  • 正文 我和宋清朗相恋三年,在试婚纱的时候发现自己被绿了。 大学时的朋友给我发了我未婚夫和他白月光在一起吃饭的照片。...
    茶点故事阅读 39,270评论 1 344
  • 序言:一个原本活蹦乱跳的男人离奇死亡,死状恐怖,灵堂内的尸体忽然破棺而出,到底是诈尸还是另有隐情,我是刑警宁泽,带...
    沈念sama阅读 34,925评论 5 338
  • 正文 年R本政府宣布,位于F岛的核电站,受9级特大地震影响,放射性物质发生泄漏。R本人自食恶果不足惜,却给世界环境...
    茶点故事阅读 40,573评论 3 322
  • 文/蒙蒙 一、第九天 我趴在偏房一处隐蔽的房顶上张望。 院中可真热闹,春花似锦、人声如沸。这庄子的主人今日做“春日...
    开封第一讲书人阅读 31,194评论 0 21
  • 文/苍兰香墨 我抬头看了看天上的太阳。三九已至,却和暖如春,着一层夹袄步出监牢的瞬间,已是汗流浃背。 一阵脚步声响...
    开封第一讲书人阅读 32,437评论 1 268
  • 我被黑心中介骗来泰国打工, 没想到刚下飞机就差点儿被人妖公主榨干…… 1. 我叫王不留,地道东北人。 一个月前我还...
    沈念sama阅读 47,154评论 2 366
  • 正文 我出身青楼,却偏偏与公主长得像,于是被迫代替她去往敌国和亲。 传闻我的和亲对象是个残疾皇子,可洞房花烛夜当晚...
    茶点故事阅读 44,127评论 2 352

推荐阅读更多精彩内容