JVM入门学习笔记——上篇:内存与垃圾回收(8-9)

文章目录

  • 8、堆(Heap)
    • 一、堆的核心概述
      • 内存细分
        • JDK7堆空间内部结构
        • JDK8堆空间内部结构
    • 二、设置堆内存大小与OOM
      • 设置堆内存大小
      • OutOfMemory(OOM)举例
    • 三、年轻代和老年代
    • 四、图解对象分配过程
      • 概述
      • 常用的调优工具
    • 五、Minor GC、Major GC、Full GC
      • 最简单的分代式GC策略的触发条件
    • 六、堆空间分代思想
    • 七、内存分配策略(对象提升(Promotion)规则)
    • 八、为对象分配内存:TLAB
    • 九、小结:堆空间的参数设置
    • 十、堆是分配对象的唯一选择吗?
      • 逃逸分析概述
      • 逃逸分析:代码优化
        • 栈上分配
        • 同步省略(消除)
        • 分离对象或标量替换
      • 逃逸分析小结:逃逸分析并不成熟
      • 本章小结
  • 9、方法区
    • 一、栈、堆、方法区的交互关系
    • 二、方法区的理解
      • 官方文档
      • 方法区在哪?
      • 方法区的基本理解
      • 方法区概述
      • Hotspot中方法区的演进
    • 三、设置方法区大小与OOM
      • 设置方法区大小
      • 代码举例1
      • 代码举例2
      • 如何解决这些OOM?
    • 四、方法区的内部结构
      • 方法区存储什么?
      • 方法区的内部结构
      • 代码举例1
      • 代码举例2
      • non-final的类变量
      • 运行时常量池 vs 常量池
      • 为什么需要常量池?
      • 常量池中有什么?
      • 运行时常量池
    • 五、方法区使用举例
    • 六、方法区的演进细节
      • JDK 1.6
      • JDK 1.7
      • JDK 1.8
      • 永久代为什么被元空间替换?
      • 静态变量放在哪里
    • 七、方法区的垃圾回收
    • 八、总结
      • 常见面试题

8、堆(Heap)

JVM入门学习笔记——上篇:内存与垃圾回收(8-9)_第1张图片
JVM入门学习笔记——上篇:内存与垃圾回收(8-9)_第2张图片

一、堆的核心概述

JVM入门学习笔记——上篇:内存与垃圾回收(8-9)_第3张图片

jvisualvm如果连接不上的话,我已经把插件的安装包放到百度云了,有需要的自取,不过只有VisualGC和jconsole plugins两个。
链接: https://pan.baidu.com/s/1YAx601tAqnRC9ZFIsL8d4A 密码:k33s
JVM入门学习笔记——上篇:内存与垃圾回收(8-9)_第4张图片
下载成功后,在已下载的添加插件这里进行安装,然后重启即可。
JVM入门学习笔记——上篇:内存与垃圾回收(8-9)_第5张图片

JVM入门学习笔记——上篇:内存与垃圾回收(8-9)_第6张图片
JVM入门学习笔记——上篇:内存与垃圾回收(8-9)_第7张图片

内存细分

JVM入门学习笔记——上篇:内存与垃圾回收(8-9)_第8张图片
永久代和元空间的区别

  • 存储位置不同:永久代物理是是堆的一部分,和新生代,老年代地址是连续的,而元空间属于本地内存。
  • 存储内容不同:元空间存储类的元信息,静态变量和常量池等并入堆中。相当于永久代的数据被分到了堆和元空间中。

JDK7堆空间内部结构

JVM入门学习笔记——上篇:内存与垃圾回收(8-9)_第9张图片

JDK8堆空间内部结构

JVM入门学习笔记——上篇:内存与垃圾回收(8-9)_第10张图片
JVM入门学习笔记——上篇:内存与垃圾回收(8-9)_第11张图片

二、设置堆内存大小与OOM

设置堆内存大小

JVM入门学习笔记——上篇:内存与垃圾回收(8-9)_第12张图片

  1. 设置堆空间大小的参数
  • -Xms:用来设置堆空间(年轻代+老年代)的初始内存大小
    • -X:是JVM的运行参数
    • ms:是memory start的缩写
  • Xmx:用来设置堆空间(年轻代+老年代)的最大内存大小
  1. 默认堆空间的大小
  • 初始内存大小:物理电脑内存大小 / 64
  • 最大内存大小:物理电脑内存大小 / 4
  1. 手动设置:-Xms600m -Xmx600m
    开发中建议将初始内存和最大内存设置成相同的值,省去堆空间扩容和释放,减少系统不必要的压力。

  2. 查看设置的参数

  • 方式一:命令行输入jps,再输入jstat -gc 进程id(进程id为jps查出的项目的进程id号)。
  • 加上JVM参数-XX:+PrintGCDetails,打印GC过程中的细节。(程序执行完后才打印)

OutOfMemory(OOM)举例

OOM:创建过多的对象或数组,把堆空间装满了。

JVM入门学习笔记——上篇:内存与垃圾回收(8-9)_第13张图片

三、年轻代和老年代

JVM入门学习笔记——上篇:内存与垃圾回收(8-9)_第14张图片
JVM入门学习笔记——上篇:内存与垃圾回收(8-9)_第15张图片

  • 新生代与老年代

默认比例为:(新生代)1    :(老年代)2

  • -XX:NewRatio=4:调整新生代和老年代的比例,4为1:4,调整的是老年代,新生代一直都为1。
    一般不会去调整,除非知道项目会有很多对象或者数组存活的时间会很长,才会去把老年代调大一些。但是调整后新生代会变小,GC回收的次数可能会相应的变多。

  • 新生代的Eden区和两个Survivor区

官方文档:新生代的Eden区和两个Survivor区的默认比例是:8 :1 :1
实际上新生代的Eden区和两个Survivor区的比例是:6 :1 :1

  • -XX:SurvivorRatio=8:调整新生代的Eden区和两个Survivor区的比例,8为8:1:1,调整的是新生代的Eden区,两个Survivor区一直分别都为1。
  • -XX:-UseAdaptiveSizePolicy:关闭自适应的内存分配策略。

JVM入门学习笔记——上篇:内存与垃圾回收(8-9)_第16张图片
JVM入门学习笔记——上篇:内存与垃圾回收(8-9)_第17张图片

四、图解对象分配过程

概述

JVM入门学习笔记——上篇:内存与垃圾回收(8-9)_第18张图片
JVM入门学习笔记——上篇:内存与垃圾回收(8-9)_第19张图片
JVM入门学习笔记——上篇:内存与垃圾回收(8-9)_第20张图片
JVM入门学习笔记——上篇:内存与垃圾回收(8-9)_第21张图片
JVM入门学习笔记——上篇:内存与垃圾回收(8-9)_第22张图片
JVM入门学习笔记——上篇:内存与垃圾回收(8-9)_第23张图片
JVM入门学习笔记——上篇:内存与垃圾回收(8-9)_第24张图片
JVM入门学习笔记——上篇:内存与垃圾回收(8-9)_第25张图片

常用的调优工具

JVM入门学习笔记——上篇:内存与垃圾回收(8-9)_第26张图片

五、Minor GC、Major GC、Full GC

JVM入门学习笔记——上篇:内存与垃圾回收(8-9)_第27张图片

最简单的分代式GC策略的触发条件

JVM入门学习笔记——上篇:内存与垃圾回收(8-9)_第28张图片
JVM入门学习笔记——上篇:内存与垃圾回收(8-9)_第29张图片
JVM入门学习笔记——上篇:内存与垃圾回收(8-9)_第30张图片
JVM入门学习笔记——上篇:内存与垃圾回收(8-9)_第31张图片

六、堆空间分代思想

在这里插入图片描述
JVM入门学习笔记——上篇:内存与垃圾回收(8-9)_第32张图片

七、内存分配策略(对象提升(Promotion)规则)

JVM入门学习笔记——上篇:内存与垃圾回收(8-9)_第33张图片
JVM入门学习笔记——上篇:内存与垃圾回收(8-9)_第34张图片

八、为对象分配内存:TLAB

JVM入门学习笔记——上篇:内存与垃圾回收(8-9)_第35张图片
JVM入门学习笔记——上篇:内存与垃圾回收(8-9)_第36张图片
JVM入门学习笔记——上篇:内存与垃圾回收(8-9)_第37张图片
JVM入门学习笔记——上篇:内存与垃圾回收(8-9)_第38张图片
-XX:UseTLAB默认开启。
JVM入门学习笔记——上篇:内存与垃圾回收(8-9)_第39张图片

九、小结:堆空间的参数设置

JVM入门学习笔记——上篇:内存与垃圾回收(8-9)_第40张图片
JVM入门学习笔记——上篇:内存与垃圾回收(8-9)_第41张图片

十、堆是分配对象的唯一选择吗?

JVM入门学习笔记——上篇:内存与垃圾回收(8-9)_第42张图片

逃逸分析概述

JVM入门学习笔记——上篇:内存与垃圾回收(8-9)_第43张图片
JVM入门学习笔记——上篇:内存与垃圾回收(8-9)_第44张图片
JVM入门学习笔记——上篇:内存与垃圾回收(8-9)_第45张图片
JVM入门学习笔记——上篇:内存与垃圾回收(8-9)_第46张图片
JVM入门学习笔记——上篇:内存与垃圾回收(8-9)_第47张图片
在这里插入图片描述

逃逸分析:代码优化

JVM入门学习笔记——上篇:内存与垃圾回收(8-9)_第48张图片

栈上分配

JVM入门学习笔记——上篇:内存与垃圾回收(8-9)_第49张图片

同步省略(消除)

JVM入门学习笔记——上篇:内存与垃圾回收(8-9)_第50张图片
JVM入门学习笔记——上篇:内存与垃圾回收(8-9)_第51张图片

分离对象或标量替换

JVM入门学习笔记——上篇:内存与垃圾回收(8-9)_第52张图片
JVM入门学习笔记——上篇:内存与垃圾回收(8-9)_第53张图片
JVM入门学习笔记——上篇:内存与垃圾回收(8-9)_第54张图片

逃逸分析小结:逃逸分析并不成熟

本章小结

JVM入门学习笔记——上篇:内存与垃圾回收(8-9)_第55张图片

9、方法区

JVM入门学习笔记——上篇:内存与垃圾回收(8-9)_第56张图片

一、栈、堆、方法区的交互关系

JVM入门学习笔记——上篇:内存与垃圾回收(8-9)_第57张图片

异常 GC
程序计数器 线程私有
虚拟机栈 StackOverflowError 线程私有
本地方法栈 StackOverflowError 线程私有
OutOfMemoryError(OOM) 线程共享
元空间 OutOfMemoryError(OOM) 线程共享

方法区是Java虚拟机规范中的定义,是一种规范,而元空间是一种实现,使用元空间来实现方法区。
JVM入门学习笔记——上篇:内存与垃圾回收(8-9)_第58张图片

二、方法区的理解

官方文档

https://docs.oracle.com/javase/specs/jvms/se8/html/jvms-2.html#jvms2.5.4
JVM入门学习笔记——上篇:内存与垃圾回收(8-9)_第59张图片
机翻:
JVM入门学习笔记——上篇:内存与垃圾回收(8-9)_第60张图片

方法区在哪?

JVM入门学习笔记——上篇:内存与垃圾回收(8-9)_第61张图片

方法区的基本理解

JVM入门学习笔记——上篇:内存与垃圾回收(8-9)_第62张图片

方法区概述

JVM入门学习笔记——上篇:内存与垃圾回收(8-9)_第63张图片

Hotspot中方法区的演进

JVM入门学习笔记——上篇:内存与垃圾回收(8-9)_第64张图片

JVM入门学习笔记——上篇:内存与垃圾回收(8-9)_第65张图片

三、设置方法区大小与OOM

设置方法区大小

JVM入门学习笔记——上篇:内存与垃圾回收(8-9)_第66张图片

代码举例1

JVM入门学习笔记——上篇:内存与垃圾回收(8-9)_第67张图片

代码举例2

JVM入门学习笔记——上篇:内存与垃圾回收(8-9)_第68张图片

如何解决这些OOM?

JVM入门学习笔记——上篇:内存与垃圾回收(8-9)_第69张图片
内存泄漏:堆空间中已经没有使用的对象始终有被引用,导致一直无法进行GC。

四、方法区的内部结构

JVM入门学习笔记——上篇:内存与垃圾回收(8-9)_第70张图片

方法区存储什么?

JVM入门学习笔记——上篇:内存与垃圾回收(8-9)_第71张图片

方法区的内部结构

JVM入门学习笔记——上篇:内存与垃圾回收(8-9)_第72张图片
JVM入门学习笔记——上篇:内存与垃圾回收(8-9)_第73张图片
JVM入门学习笔记——上篇:内存与垃圾回收(8-9)_第74张图片

代码举例1

JVM入门学习笔记——上篇:内存与垃圾回收(8-9)_第75张图片

代码举例2

JVM入门学习笔记——上篇:内存与垃圾回收(8-9)_第76张图片

non-final的类变量

JVM入门学习笔记——上篇:内存与垃圾回收(8-9)_第77张图片
JVM入门学习笔记——上篇:内存与垃圾回收(8-9)_第78张图片

运行时常量池 vs 常量池

JVM入门学习笔记——上篇:内存与垃圾回收(8-9)_第79张图片
JVM入门学习笔记——上篇:内存与垃圾回收(8-9)_第80张图片
JVM入门学习笔记——上篇:内存与垃圾回收(8-9)_第81张图片
JVM入门学习笔记——上篇:内存与垃圾回收(8-9)_第82张图片

为什么需要常量池?

JVM入门学习笔记——上篇:内存与垃圾回收(8-9)_第83张图片

常量池中有什么?

JVM入门学习笔记——上篇:内存与垃圾回收(8-9)_第84张图片
JVM入门学习笔记——上篇:内存与垃圾回收(8-9)_第85张图片

运行时常量池

五、方法区使用举例

JVM入门学习笔记——上篇:内存与垃圾回收(8-9)_第86张图片
JVM入门学习笔记——上篇:内存与垃圾回收(8-9)_第87张图片
JVM入门学习笔记——上篇:内存与垃圾回收(8-9)_第88张图片
JVM入门学习笔记——上篇:内存与垃圾回收(8-9)_第89张图片
JVM入门学习笔记——上篇:内存与垃圾回收(8-9)_第90张图片
JVM入门学习笔记——上篇:内存与垃圾回收(8-9)_第91张图片
JVM入门学习笔记——上篇:内存与垃圾回收(8-9)_第92张图片
JVM入门学习笔记——上篇:内存与垃圾回收(8-9)_第93张图片
JVM入门学习笔记——上篇:内存与垃圾回收(8-9)_第94张图片
JVM入门学习笔记——上篇:内存与垃圾回收(8-9)_第95张图片
JVM入门学习笔记——上篇:内存与垃圾回收(8-9)_第96张图片
JVM入门学习笔记——上篇:内存与垃圾回收(8-9)_第97张图片
JVM入门学习笔记——上篇:内存与垃圾回收(8-9)_第98张图片
JVM入门学习笔记——上篇:内存与垃圾回收(8-9)_第99张图片
JVM入门学习笔记——上篇:内存与垃圾回收(8-9)_第100张图片
JVM入门学习笔记——上篇:内存与垃圾回收(8-9)_第101张图片
JVM入门学习笔记——上篇:内存与垃圾回收(8-9)_第102张图片

六、方法区的演进细节

JVM入门学习笔记——上篇:内存与垃圾回收(8-9)_第103张图片

JDK 1.6

JVM入门学习笔记——上篇:内存与垃圾回收(8-9)_第104张图片

JDK 1.7

JVM入门学习笔记——上篇:内存与垃圾回收(8-9)_第105张图片

JDK 1.8

JVM入门学习笔记——上篇:内存与垃圾回收(8-9)_第106张图片

永久代为什么被元空间替换?


机翻:
JVM入门学习笔记——上篇:内存与垃圾回收(8-9)_第107张图片
JVM入门学习笔记——上篇:内存与垃圾回收(8-9)_第108张图片
JVM入门学习笔记——上篇:内存与垃圾回收(8-9)_第109张图片

静态变量放在哪里

JVM入门学习笔记——上篇:内存与垃圾回收(8-9)_第110张图片
JVM入门学习笔记——上篇:内存与垃圾回收(8-9)_第111张图片
JVM入门学习笔记——上篇:内存与垃圾回收(8-9)_第112张图片
JVM入门学习笔记——上篇:内存与垃圾回收(8-9)_第113张图片

个人理解:

  • 静态变量在JDK1.6和1.7、1.8中,都是放在老年代里的。
  • new出来的对象始终都是在堆空间的。
  • 只有变量名(引用名)在三个版本中发生了变化,JDK1.6时是在方法区(永久代)中,JDK1.7和1.8时都在堆空间。
  • 方法内的局部变量的变量名是放在栈(局部变量表)上的,而类的成员变量和静态变量的变量名是放在元空间的(放在堆里)。未发生逃逸的在栈上(因为标量替换),发生逃逸的在堆上。

以上为个人的理解,如果理解错了,请各位大大指出。

七、方法区的垃圾回收

JVM入门学习笔记——上篇:内存与垃圾回收(8-9)_第114张图片
JVM入门学习笔记——上篇:内存与垃圾回收(8-9)_第115张图片

方法区关于垃圾回收,常量的回收比较简单,但是类型的回收就会比较麻烦,需要满足三个条件才能进行回收。

八、总结

JVM入门学习笔记——上篇:内存与垃圾回收(8-9)_第116张图片

常见面试题

JVM入门学习笔记——上篇:内存与垃圾回收(8-9)_第117张图片
JVM入门学习笔记——上篇:内存与垃圾回收(8-9)_第118张图片

下一篇笔记:JVM入门学习笔记——上篇:内存与垃圾回收(10-13)

学习视频(p66-p101):https://www.bilibili.com/video/BV1PJ411n7xZ?p=66

你可能感兴趣的:(JVM)