JVM

本文章是笔者对《深入理解java虚拟机》第2版这本书(基于jdk1.7)的理解和简要概括。

第二章    java内存区域和内存溢出异常

2.2 运行时数据区域

包括五个部分:程序计数器(PC计数器)、虚拟机栈、本地方法栈、堆、方法区。前三个是线程独立的,而后两个是线程共享的区域。

2.2.1 程序计数器

分为两种情况,当前线程正在执行java方法时,程序计数器保存的是正在执行的虚拟机字节码指令的地址;当前线程正在执行Native方法时,程序计数器的值为空。

(Native方法:是由java关键字native修饰的方法,表示当前方法的实现是由其他语言实现的,保存在本地的DLL文件中,当方法被调用时,DLL文件会被加载。当前方法只是一个调用接口)。

2.2.2 虚拟机栈

每个方法在执行的时候都会创建一个对应的栈帧,虚拟机栈就是保存这些栈帧的,而方法的调用和结束对应的是栈帧的入栈和出栈。

栈帧包括:局部变量表、操作数栈、动态链接、方法出口等信息。

局部变量表:存放了编译期可知的基本类型数据(int,boolean等)、对象引用和returnAddress类型(指向一条字节码指令的地址)。它的大小是在编译期就完成分配了。

2.2.3 本地方法栈

与虚拟机栈类似,虚拟机栈是为虚拟机使用java方法服务,而本地方法栈是为虚拟机使用Native方法服务。

2.2.4 堆

存放的是对象实例和数组。

虽然堆是线程共享的,但是有的虚拟机在实现的时候会为线程在堆里面独立地分配一个缓冲区(TLAB),目的是加快内存分配和更好地回收内存。

2.2.5 方法区

主要存放的是已被虚拟机加载的类信息、常量、静态变量等。

方法区中有一个区域叫做运行时常量池,是用来存放编译期生成的各种字面量(如1或者“ad”这样的)和符号引用(jdk1.7开始加入的特征),他们是在类加载后才进入方法区的运行时常量池的。

2.3 HotSpot虚拟机对象

2.3.1 对象的创建

两种方式:指针碰撞和空闲列表

指针碰撞:当堆内存是绝对规整时:使用过的内存在一边,空白的在一边,中间是一个指针。当需要为对象分配内存时,只需要指针向后移动对象大小的内存空间即可。

空闲列表:当堆内存不是规则时,虚拟机会维护一个空闲空间列表。当为对象分配内存时,虚拟机会找到一个满足大小的空间给对象。

2.3.2 对象的内存布局

对象在内存中的存储布局分成三个部分:对象头,实例数据和对齐填充。

对象头:包括Mark Word自身运行时数据(如哈希码,GC分代年龄,锁状态标志,线程持有的锁等)和类型指针(指向对象的类的元数据)。

实例数据:对象的有效信息,是代码中定义的各种类型的字段内容。

对齐填充:HotSpot VM要求对象的起始地址为8字节的倍数,所以当对象大小不够8的倍数时,用来填充的。

2.3.3 对象的访问

使用句柄:堆中分出一块内存作为句柄池。虚拟机栈中保存对象的引用,指向堆中一个句柄。句柄包括指向对象实例数据(在堆中)的指针和指向对象类型数据(在方法区)的指针。

直接指针:虚拟机栈中保存对象的引用,指向堆中一个对象(对象包含实例数据),同时对象里面有一个指针指向对象类型数据。

好处:前者——对象发生变化(如对象被移动)时,栈中引用本身不需要修改。后者——可以提高访问数据的效率。

2.4 内存溢出错误(OOM)

程序计数器是唯一一个不会发生OutOfMemoryError异常的地方,而其他四个都可能发生异常。

2.4.1 堆溢出

当堆中不能再创建对象且堆大小不能扩展的时候,堆就出现内存溢出的异常。

可能的原因有内存泄漏(某些不需要的对象没有被垃圾收集器回收)和内存溢出(存活的对象确实都是需要存在的)。

对应的解决办法是:内存泄漏——查看泄漏对象的类型信息和GC Roots引用链的信息,定位泄漏代码位置。内存溢出——尝试调大堆内存或者看看哪些对象的生命周期可以调小。

2.4.2 虚拟机栈和本地方法栈溢出

HotSpot虚拟机不区分这两块区域。他们可能出现的异常有两个原因。

1)如果线程请求的栈深度大于虚拟机允许的栈深度,就会抛出StackOverflowError异常。(如一个方法无限递归调用,线程中方法的栈帧过多)。

2)如果虚拟机在扩展栈的时候不能申请到足够的空间,就会抛出OutOfMemoryError异常。(如多个线程都持有栈,当再次创建一个线程时没有足够空间)。

2.4.3 方法区和运行时常量池溢出

运行时常量池存在动态性,即java允许在程序执行的过程中创建常量,所以当运行时常量池的大小不够时,就会出现溢出。

intern方法:动态创建常量如String类的intern方法,JDK1.6以前intern方法会把首次遇到的字符串复制到常量池中,然后返回它的引用。JDK1.7以后,intern方法直接复制首次出现的字符串的引用,然后返回此引用。

持续更新中

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