JVM学习笔记

1. JVM运行时数据区域

1.1. 程序计数器

  • 是一块较小的内存空间,可以看作是当前线程所执行的字节码的行号指示器
  • 每条线程都有一个独立的程序计数器,各条线程之间计数器互不影响,独立存储,这类内存区域被称为“线程私有”的内存。
  • 是唯一一个在JVM规范中没有规定任何OutOfMemoryError情况的区域。

1.2. 虚拟机栈

  • 描述的是Java方法执行的内存模型:每个方法在执行的同时都会创建一个栈帧用于存储局部变量表、操作数栈、动态链接、方法出入口等信息。每个方法从调用到执行完成的过程,就对应着一个栈帧在虚拟机栈中入栈到出栈的过程。
  • 也是线程私有的,其生命周期与线程相同。
  • 局部变量表存放了编译器可知的各种基本数据类型,所需的内存空间在编译期间完成分配。
  • 这个区域有两种异常状况:如果线程请求的栈深度大于虚拟机所允许的深度,将抛出StackOverflowError异常;如果动态扩展虚拟机栈时,无法申请到足够的内存,就会抛出OutOfMemoryError异常。

1.3. 本地方法栈

  • 和虚拟机栈作用相似,只不过虚拟机栈为虚拟机执行Java方法(字节码)服务,而本地方法栈则为虚拟机使用到的Native方法服务。
  • 抛出的两种异常也与虚拟机栈相同。

1.4. Java堆

  • 被所有线程共享的内存区域,在虚拟机启动时创建。此区域的唯一目的就是存放对象实例,几乎所有的对象实例都在这里分配内存。
  • Java堆中还可以细分为:新生代和老年代;Eden、From Survivor、To Survivor空间等;多个线程私有的分配缓冲区(TLAB)。
  • 可以处于物理上不连续的内存空间,只要逻辑上是连续的即可。
  • 可以实现成固定大小的,也可以是可扩展的。
  • 如果在堆中没有内存完成实例分配,并且堆也无法再扩展时,将会抛出OutOfMemoryError异常。

1.5. 方法区

  • 是各个线程共享的内存区域,用于存储已被虚拟机加载的类信息、常量、静态变量、即时编译器编译后的代码等数据。
  • HotSpot虚拟机中的方法区常被称为“永久代”,可以像管理Java堆一样管理方法区,但这样更容易遇到内存溢出的问题。现在,HotSpot虚拟机已经逐步改为采用Native Memory来实现方法区了。
  • JVM规范中,方法区可以选择不实现垃圾收集。
  • 当方法区无法满足内存分配的需求时,将抛出OutOfMemoryError异常。

1.6. 运行时常量池

  • 方法区的一部分,用于存放编译期生成的各种字面量和符号引用,在类加载后进入方法区。
  • 对运行时常量池的格式,JVM规范没有做任何细节的要求,不同的提供商实现的虚拟机可以按照自己的需要来实现这个内存区域。
  • Java语言并不要求常量一定只有编译器才能产生,运行期间也可能将新的常量放入池中,如String类的intern()方法。
  • 当常量池无法再申请到内存时,会抛出OutOfMemoryError异常。

1.7. 直接内存

  • 并不是虚拟机运行时数据区的一部分,也不是JVM规范中定义的内存区域。但是这部分内存也被频繁地使用,而且也可能导致OutOfMemoryError异常出现。
  • JDK 1.4中新加入了NIO类,引入了一种基于通道与缓冲区的I/O方式。使用Native函数库直接分配堆外内存,然后通过一个存储在Java堆中的DirectByteBuffer对象作为这块内存的引用进行操作。这样避免了在Java堆和Native堆之间来回复制数据,能在一些场景中显著提高性能。
  • 直接内存的分配不会收到Java堆大小的限制,但是还是会受到本机总内存的限制。

2. HotSpot虚拟机对象探秘

2.1. 对象的创建

  • 当虚拟机遇到一条new指令时,首先检查这个指令的参数能否在常量池中定位到一个类的符号引用,并且检查这个符号引用代表的类是否已被加载、解析和初始化过。如果没有,那必须先执行相应的类加载过程
  • 在类加载检查通过后,虚拟机将为新生对象分配内存。对象所需内存的大小在类加载完成后便可完全确定,为对象分配空间的任务等同于把一块确定大小的内存从Java堆中划分出来。
  • 如果堆内存是规整的,则使用指针碰撞的分配方式(Serial、ParNew),否则使用空闲列表(CMS)。
  • 并发情况下的线程安全问题的解决方案:
    • 对分配内存空间的动作进行同步处理。虚拟机采用CAS加上失败重试的方式保证更新操作的原子性。
    • 把内存分配的动作按照线程划分在不同的空间之中进行,即每个线程在堆中预先分配一小块内存(TLAB)。只有TLAB用完并分配新的TLAB时,才需要同步锁定。
  • 接下来,虚拟机要对对象进行必要的设置,例如这个对象是哪个类的实例,如何才能找到类的元数据信息、对象的哈希码、对象的GC分代年龄等信息。这些信息存放在对象的对象头之中。根据虚拟机当前的运行状态的不同,如是否启用偏向锁等,对象头会有不同的设置方式。
  • 执行new指令之后,接着执行<init>方法,把对象按照程序员的意愿进行初始化。

2.2. 对象的内存布局

  • 对象头
    • 一部分用于存储对象自身的运行时数据,如哈希码、GC分代年龄、锁状态标志、线程持有的锁、偏向线程ID、偏向时间戳等。这部分数据的长度在32位和64位的虚拟机中分别为32bit和64bit,官方称之为“Mark Word”。
    • 另一部分是类型指针,即对象指向它的类元数据的指针,虚拟机通过这个指针来确定这个对象是哪个类的实例。如果对象是一个数组,则还需要有一块用于记录数组长度的数据。
  • 实例数据:是对象真正存储的有效信息,也是在程序代码中所定义的各种类型的字段内容。
  • 对齐填充:并不是必然存在的,也没有特别的含义,仅仅起着占位符的作用。

2.3. 对象的访问定位

通过栈上的reference数据来操作堆上的具体对象,对象的访问方式取决于虚拟机的实现:

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

推荐阅读更多精彩内容

  • 简介 Java与C++之间有一堆由内存动态分配与垃圾收集技术所围成的“高墙”,墙外面的人想进去,墙里面的人却想出来...
    黄俊彬阅读 953评论 2 14
  • JVM内存模型Java虚拟机(Java Virtual Machine=JVM)的内存空间分为五个部分,分别是: ...
    光剑书架上的书阅读 2,467评论 2 26
  • Java创建对象的过程 简单记录一下Java创建对象的过程,就是new一个对象的时候发生了哪些事情。Java程序执...
    加大装益达阅读 1,068评论 0 0
  • 一,下载 1. 首先,下载最新的python,Mac OS上默认应该是内置python,但不是最新的。 最新下载网...
    潘老6阅读 544评论 0 3
  • (四)初见 江城市不是很大,但是绿化特别好,比如我上学的路上就要路过两个公园,三中周围也种着许多树,门前...
    沈白_阅读 179评论 0 0