笔记:JVM、对象分析与垃圾回收机制剖析

JVM(Java Virtual Machine) Java虚拟机

JVM与操作系统.png
  • JVM 全称 Java Virtual Machine,也就是我们耳熟能详的 Java 虚拟机。它能识别 .class后缀的文件,并且能够解析它的指令,最终调用操作系统上的函数,完成我们想要的操作。它是可以跨语言跨平台的
    过程如下:Java 文件->编译器>字节码->JVM->机器码。


    执行过程.png

解释执行与JIT的区别:对字节码逐条解释执行,这种方式的执行速度相对会比较慢,尤其当某个方法或代码块运行的特别频繁时,这种方式的执行效率就显得很低。于是后来在虚拟机中引入了JIT编译器(即时编译器),当虚拟机发现某个方法或代码块运行特别频繁时,就会把这些代码认定为“Hot Spot Code”(热点代码),为了提高热点代码的执行效率,在运行时,虚拟机将会把这些代码编译成与本地平台相关的机器码,并进行各层次的优化,完成这项任务的正是JIT编译器。

  • JVM区域划分


    JVM模型图.png
    • 线程私有的区域:
      1.虚拟机栈:虚拟机栈在JVM运行过程中存储当前线程运行方法所需的数据,指令、返回地址。虚拟机栈由一个个方法的存储区域 每个方法为一个栈帧。栈帧包括:操作数栈、局部变量表(存储方法中定义的变量)、动态连接(Java语言特性多态需要类运行时才能确定具体的方法)、完成出口(返回地址)。
      2.本地方法栈:调用native方法,本地方法栈跟 Java 虚拟机栈的功能类似,Java 虚拟机栈用于管理 Java 函数的调用,而本地方法栈则用于管理本地方法的调用。但本地方法并不是用 Java 实现的,而是由 C 语言实现的。
      本地方法栈是和虚拟机栈非常相似的一个区域,它服务的对象是 native 方法。你甚至可以认为虚拟机栈和本地方法栈是同一个区域。
      虚拟机规范无强制规定,各版本虚拟机自由实现 ,HotSpot直接把本地方法栈和虚拟机栈合二为一 。
      3.程序计数器:较小的内存空间,当前线程执行的字节码的行号指示器;各线程之间独立存储,互不影响。空间较小 jvm中唯一不会OOM的区域。记录当没有cpu执行权时当前程序执行到哪一条字节码指令。下次拿到执行权继续从这条指令下去
      字节码助记码解释地址:https://cloud.tencent.com/developer/article/1333540
      栈帧的解释

      在JVM中,基于解释执行的这种方式是基于栈的引擎,这个说的栈,就是操作数栈。
      基于栈:移植性好 但是需要编译
      基于寄存器:直接执行机器码 速度快 但是移植性差
    • 线程共享的区域:
      分成方法区和堆区的主要目的是实现动静分离。(堆区一般存放对象实例,回收比较频繁,而方法区 通常存放一些常量)
      1.方法区:一般存放 类信息、静态变量、常量、即时编译的代码。
      <=jdk1.7一般称为永久代 :受限于堆的大小
      >=jdk1.8 一般称为元空间:可使用机器内存 好处方便拓展,坏处挤压堆空间
      2.堆:一般存放对象 数组
    • HSDB内存查看工具sa-jdi.jar
  • 造成内存溢出的几个原因:
    1.栈溢出:只压栈不弹栈(导致分配内存空间不足)
    2.方法区溢出,CGLIB直接操作字节码运行时,生成大量的动态类。
    3.堆溢出:没有连续内存分配给对象,空间不足

  • 虚拟机优化技术:
    1.方法内联
    2.栈帧之间数据共享

java对象的简析(对象的诞生)

  • 对象的创建过程:
    类加载->检查加载->分配内存->内存初始化->设置(属于哪个class,对象头...)->对象初始化


    对象的创建.png

    新建对象分配内存的方式:
    1.指针碰撞:移动一个对象大小的空间
    2.空闲列表
    对象的内存布局:


    对象的内存布局.png

    对象补充:一般对象的大小不是字节的整数倍 会补充到整个对象的大小成为整数倍
  • 对象的定位:
    1.使用句柄
    2.直接指针:java采用采用直接指针


    image.png
  • 判断对象是否存活的方法:


    image.png

1.引用计数法:当对象被引用时 计数器+1 对象被置空时 计数器-1,计数简单 但是存在 内部互相引用不释放无法判断解开引用的情况
2.可达性分析(根可达),以GCRoots为根
GCRoots:静态变量 线程栈变量 常量池 JNI指针,异常 ,锁

  • 常见的各种引用:
    1.强引用:
Object o  = new Object()  ,= 就是强引用

2.软引用:gc时内存不足时会被回收

 SoftReference<Object> soft = new SoftReference(o);

3.弱引用:gc时会被回收

 WeakReference<Object> weak = new WeakReference(o);

4.虚引用:随时会被回收

 PhantomReference<Object> phantom = new PhantomReference(o);
  • 对象分配策略:
    1.几乎所有的对象都是在堆上分配,符合逃逸分析的会在栈上分配
    2.堆区的划分:


    堆区分配.png

    对象优先在Eden分配
    空间分配担保
    大对象直接进入老年代
    长期存活的对象进入老年代
    动态对象年龄判定
    新生代:Eden From To (8:1:1)(采用复制算法)=
    老年代:存放长期存活对象和大对象

垃圾回收机制(对象的死亡 GC)

垃圾回收算法:
1.复制算法:直接复制一半有用的内存对象到另外一半内存 然后清空原先的内存


复制算法.png

特点:实现简单,运行高效 ,没有内存碎片;但是内存利用率只有一半
2.标记清除算法:对需要回收的对象进行标记进行清除


标记-清除.png

特点:执行效率不稳定,内存碎片化导致提取GC
3.标记整理算法:标记清除的算法上对内存上的对象进行移动规整
标记整理.png

特点:
对象移动
引用更新
用户线程暂停
没有内存碎片

  • 分代回收:


    image.png

    之所以新生代分为8:1:1的原因是为了提高效率。大部分eden区的对象存活时间比较短。 如果直接使用复制算法而不开辟from和to区 会导致内存利用率减低

  • 对象移动顺序:


    image.png
  • 垃圾回收器:


    回收示意图.png
垃圾回收器.png

CMS:


image.png
  • STW(stop the world)
    暂停所有工作线程


    STW.png

G1:(android 未采用g1)


G1.png

常量池与String

image.png

QA

1. JVM内存结构说一下!

A:从线程私有的 虚拟机栈
虚拟机里会包含栈帧
栈帧又可以分为操作数栈 局部变量表 动态链接 完成出口;
程序计数器 记录当前执行的指令
本地方法栈 主要调用本地的native方法
线程共享的有方法区 存放常量 静态变量 对象引用 和堆 存放对象数组 对象实例

2.什么情况下内存栈溢出?

A:方法只进不出 只压栈不弹栈

3.描述new一个对象的流程!

A: 首先会检查class是否已加载如果未加载 先从classLoader加载class。然后开始分配内存 初始化内存,进行对象头 class实例引用 年龄分代等信息的设置 设置完成后开始对象实例的初始化。

4.Java对象会不会分配在栈中?

A:符合逃逸分析的会被分配在栈中

5. 如果判断一个对象是否被回收,有哪些算法,实际虚拟机使用得最多的是什么?

A:如果使用引用计数法 可以看引用数是否为0 如果使用根可达性分析 则需要根据引用链分析是否可达引用,实际使用的是可达性分析

6.GC收集算法有哪些?他们的特点是什么?

A:复制算法:实现简单 效率块,但是内存利用率低
标记-清除算法:效率不稳定 有内存碎片化 容易导致提前gc
标记-整理算法:重新指向引用,无内存碎片化,用户线程需要暂停,对象会被移动

7.JVM中一次完整的GC流程是怎样的?对象如何晋级到老年代?

A:首先一般的对象分配在新生代的eden区 经过一次垃圾回收后进入 from区 在from区和to区存放对象年龄超过15就会进入老年代 或者 from 区或to区空间不足那么 对象占用较大的会直接晋升老年代

8.Java中的几种引用关系,他们的区别是什么?

A:强弱软虚 强引用要主动释放才会回收 虚引用随时可能被回收 弱引用 gc时会被回收 而软引用会在gc时空间不足被回收

9.final、finally、finalize的区别?

A:final 修饰类 则类不可再被继承,修饰 变量则 变量不可再更改
finally:try{}finally{},try{}catch(XXX){}finally{} 最后都会执行finally块里的内容
finalize:对象被回收的回调 (优先级很低)

10.String s = new String(“xxx”);创建了几个对象?

A:2个 分配xxx到常量池1次 new 指向1次

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

推荐阅读更多精彩内容