《深入理解Java虚拟机》笔记--Java内存与内存溢出

一.JAVA内存

1.运行时数据区域

线程隔离区:程序计数器,虚拟机栈,本地方法栈
线程共享区:方法区,堆

1.1程序计数器

多线程是通过线程轮流切换并分配处理器执行时间的方式来实现的,在任何一个时刻,一个处理器(对于多核处理器来说是一个内核)都只会执行一条线程的指令。因此,为了线程切换后能恢复到正确的执行位置,每条线程都需要有一个独立的程序计数器,各个线程直接计数器互不影响,独立存储。

  • 当前线程所执行的字节码的行号指示器,是一块较小的内存空间
  • 如果是Java代码,则记录的是正在执行的虚拟机字节码指令的地址,如果是native方法,则为空
  • 唯一没有任何规定OOM的区域

1.2虚拟机栈

粗糙的将Java内存分为堆和栈,那这里的“栈”指的就说虚拟机栈,或者说是虚拟机栈中的局部变量表部分

  • 描述的是Java方法执行的内存模型:每个方法在执行时都会创建一个栈帧,用于存储 局部变量表、 操作数栈、动态链接、方法出口等信息。每一个方法从调用直至执行完成的过程就对应一个栈帧在虚拟机栈中入栈道出栈的过程
  • 局部变量表存放了编译期可知的各种基本数据类型、对象引用、和returnAdrdress类型
  • 当进入一个方法时,这个方法需要在帧中分配多大的局部变量空间时完全确定的,在方法运行期间不会改变局部变量表的大小
  • 栈溢出 线程请求的栈深度大于虚拟机所允许的深度
  • OOM 如果拓展时无法申请到足够的内存

1.3本地方法栈

与虚拟机栈的区别是,为虚拟机所用到的Native方法服务

1.4堆

是虚拟机所管理的内存中最大的一块,是线程共享的,在虚拟机启动时创建。

  • 堆的唯一目的就是存放对象实例,几乎所有的对象实例都在这里分配内存
  • 堆是垃圾收集器管理的主要区域,因此被称为“GC堆”
  • 堆可以是物理上不连续的内存空间,只要逻辑上说连续的即可
  • 堆无法拓展时会OOM

1.5 方法区

线程共享,用于存储意已被虚拟机加载的类信息、常量、静态变量、即时编译器编译后的代码等数据。

  • 垃圾收集行为出现较少,主要回收是针对常量池和类型的卸载
  • 当无法满足内存分配需求时会OOM
1.5.1运行时常量

是方法区的一部分,用于存放编译期生成的各种字面量和符号引用,这部分内容将在,类加载后进入方法区的运行时常量池中,存放

  • 动态性:Java语言并不要求常量一定只有编译期才能产生,也就说并非预置入class文件中常量池的内容才能进入方法区运行时常量池,运行期间也可能将新的常量池放入池中,这种特效被开发人员利用得比较多的便是String类的intern()方法

2.HotSpot虚拟机对象

2.1对象的创建

1.new关键字开始
2.类加载检查
3.分配内存
4.内存空间初始化为零值(不包括对象头)
5.设置
6.执行Init

类加载检查

  • 检查new指令的这个参数是否能在常量池中定位到一个类的符号引用,并且检查这个符号引用代表的类是否已被加、解析、和初始化过,如果没有,则必须先执行对应的类加载过程

分配内存

  • 垃圾收集器是否带有压缩整理功能决定Java堆是否规整
  • Java堆不规整-分配方式-空闲列表-虚拟机维护一个列表,记录哪些内存块说可用的
  • Java堆规整-分配方式-指针碰撞-用过的内存在一边,空闲的在一边,中间放着指针作为分界点的指示器,分配内存仅仅是把指针移动对象大小相等的距离
  • 同步方案1-虚拟机采用CAS配上失败重试的方式保证更新操作的原子性
  • 同步方案2-把内存分配的动作按照线程划分在不同的空间中进行(本地线程分配缓冲)

初始化为零值

  • (疑问)保证了对象实例字段在Java代码中可用不赋值就直接使用,程序能访问到这些字段的数据类型所对应下来的零值

设置

  • 设置这个对象是哪个类的实例、如何才能找到类的元数据信息、对象的哈希、对象的GC分代年龄等信息。这些信息保存在对象头中(Object Header)

执行Init

  • 执行new关键字后,会执行init方法,把对象按照程序等意愿进行初始化,这样一个真正的对象才算完成产出

2.2对象的内存布局

在HotSpot虚拟机中,对象在内存中的存储布局可以分为3块区域:对象头、实例数据、对齐填充

对象头

对象头包括两部分信息

  1. 用于存储对象自身的运行时数据:哈希码、GC分代年龄、锁状态标志、线程持有锁、偏向线程ID、偏向时间戳等
  2. 存储类型指针,即指向它的类元数据的指针,虚拟机通过这个指针来确定这个对象是哪个类的实例。(查找元数据并不一定要经过对象本身 )

注:如果是Java数组,那么对象头中还必须要有一块区域用于记录数组长度的数据,因为Java虚拟机可以通过普通Java对象的元数据信息来确定Java对象的大小,但是从数组的元数据中无法确定数组的大小

实例数据

实例数据是对象真正存储的有效信息,也就说程序代码中所定义的各种类型的字段内容,无论是从父类继承下来的,还是本身定义的,都要记录下来

对齐填充

对齐填充部必然存在,因为对象的大小必须说8字节的倍数,当对象实例数据部分没有对齐时,就要通过对齐填充来补齐

2.3对象的访问定位

Java程序需要通过栈上的reference数据来操作上的具体对象。由于reference类型值规定来一个指向对象的引用,而具体引用的方式目前有两种:使用句柄、直接指针
tip:reference类型存储在虚拟机栈的栈帧中的局部变量表中

二.outOfMemoryError异常

虚拟机规范中描述:除了程序计数器外,其他的运行时区域都有发生OOM的可能

1.Java堆溢出

Java堆用于存储对象实例,只要不要地创建对象,并且保证GC Root到对象之间有可达路径来避免垃圾回收机制来清除这些对象,那么在对象数量到达最大堆的容量限制后就会产生内存溢出异常

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

由于HotSpot虚拟机并不区分虚拟机栈和本地方法栈(只是分别执行Java方法和native方法),因此虽然设置本地方法栈大小存在,但实际上上无效的,栈容量由虚拟机栈容量确定

    1. 如果线程请求的栈深度大于虚拟机允许的最大深度,将会抛出StackOverflowError异常
  • 2.如果虚拟机栈的拓展栈时无法申请到足够的内存空间,则抛出OutOfMemoryError异常

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

运行时常量池上方法区的一部分

  • 如果虚拟机栈的拓展栈时无法申请到足够的内存空间,则抛出OutOfMemoryError异常

4.本地直接内存溢出

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

推荐阅读更多精彩内容