✅P144_性能压测-性能监控-堆内存与垃圾回收

gong_yz大约 3 分钟谷粒商城

开篇

影响性能的因素:数据库、应用程序、中间件、网络和操作系统

优化首先考虑应用属于CPU密集型还是IO密集型


一、jvm 内存模型

JVM的内存模型

1.1 程序计数器 Program Counter Register

  • 记录的是正在执行的虚拟机字节码指令的地址,
  • 此内存区域是唯一一个在JAVA虚拟机规范中没有规定任何OutOfMemoryError的区域

1.2 虚拟机:VM Stack

  • 描述的是 JAVA 方法执行的内存模型, 每个方法在执行的时候都会创建一个栈帧,用于存储局部变量表操作数栈动态链接方法接口等信息
  • 局部变量表存储了编译期可知的各种基本数据类型、 对象引用
  • 线程请求的栈深度不够会报 StackOverflowError 异常
  • 栈动态扩展的容量不够会报 OutOfMemoryError 异常
  • 虚拟机栈是线程隔离的, 即每个线程都有自己独立的虚拟机栈

1.3 本地方法:Native Stack

本地方法栈类似于虚拟机栈, 只不过本地方法栈使用的是本地方法

1.4 堆: Heap

几乎所有的对象实例都在堆上分配内存


二、堆

所有的对象实例以及数组都要在堆上分配。 堆是垃圾收集器管理的主要区域, 也被称为“GC堆” ; 也是我们优化最多考虑的地方。

堆可以细分为:

  • 新生代
    • Eden 空间
    • From Survivor 空间
    • To Survivor 空间
  • 老年代
  • 永久代/元空间
    • Java8 以前永久代, 受 jvm 管理, java8 以后元空间, 直接使用物理内存。 因此,默认情况下, 元空间的大小仅受本地内存限制。

垃圾回收

从 Java8 开始, HotSpot 已经完全将永久代(Permanent Generation) 移除, 取而代之的是一个新的区域—元空间(MetaSpace)。

垃圾回收机制过程:

  • 当系统产生了一个新的对象,需要为其分配内存空间,首先考虑的是在堆中的新生代(Eden)中能否放得下;如果放得下则直接存储,如果放不下则会进行一次快速的YGC;如果YGC之后还放不下则判断老年代能否放下,如果放得下则直接存储,如果放不下则会触发一次FullGC,FullGC之后还放不下则会报异常。
  • YGC的过程则是判断幸存区是否能放下旧对象,如果可以放下则直接存储,每次YGC这些对象的年龄就会增加1,到15岁时就会迁移到老年代。如果放不下则判断老年代是否能放下。