JVM重点知识总结

一、JVM内存模型

  • JVM将内存分为5大区域:程序计数器、虚拟机栈、本地方法栈、堆、方法区

1. 程序计数器

  • 线程私有的,是一块很小的内存空间。作为当前线程的行号指示器,用于记录当前虚拟机正在执行的线程指令。
  • 唯一一个不会发生OOM的区域

2. 虚拟机栈

  • 线程私有的,每个方法执行的时候都会创建一个栈帧,用于存储局部变量表、操作数栈、动态链接和方法的返回等信息。
  • 当线程请求的栈深度超过了虚拟机允许的最大深度时,跑出StackOverFlowError异常

3. 本地方法栈

  • 线程私有的,保存的是native方法的信息。
  • 当一个jvm创建的线程调用native方法后,jvm不会在虚拟机栈中为该线程创建栈帧。而是简单的动态链接并直接调用该方法。

4. 堆

  • 线程共享。几乎所有对象的实例和数组都要在堆上分配内存

5. 方法区

  • 存放已经被加载的类信息、常量、静态变量和即时编译器编译后的代码数据,即永久代。

  • 在jdk1.8之后,被元数据区取代。原方法区分成两部分:

    • 加载的类信息:保存在元数据区
    • 运行时常量池:保存在堆中

二、JVM垃圾回收器

img

1. 串行垃圾回收器

  • 串行垃圾回收器只会使用一个CPU或一个收集线程完成垃圾收集工作。并且在垃圾回收的时候,必须暂停其他所有的工作线程(Stop the World),直到收集完成。

  • 串行垃圾回收器有两种:Serial、Serial Old,一般搭配使用。通过**-XX:+UseSerialGC开启**

  • Serial:新生代、复制算法

  • Serial Old:老年代、标记整理算法

2. 并行垃圾回收器

  • 并行垃圾回收器通过多线程运行垃圾收集,也会Stop the World。适合Server模式以及多CPU环境,一般会和CMS搭配使用。

  • ParNew:新生代、复制算法。Serial的多线程版本,默认开启的收集线程数和CPU数量一样。通过-XX:+UseParNewGC开启和Serial Old收集器组合进行内存回收

  • Parallel Scavenge:**新生代、复制算法。**关注吞吐量(吞吐量=代码运行时间 / (代码运行时间+垃圾手机时间))。高效率利用CPU时间。

  • Parallel Old:老年代、标记整理法。Parallel Scavenge的老年代版本。一般使用Parallel Scavenge+Parallel Old组合使用

3. CMS收集器

  • CMS(Concurrent Mark Sweep)收集器是一种以获得最短回收停顿时间为目的的收集器。采用标记清除算法
  • 运作过程:初始标记、并发标记、重新标记、并发清除收集结束会产生大量空间碎片
    • 初始标记:标记一下GC Roots能直接关联到的对象,会Stop the World
    • 并发标记:GC Roots Tracing,可以和用户线程并发执行
    • 重新标记:标记期间产生的对象存活的再次判断,修正对这些对象的标记,执行时间相对并发标记短,会Stop the World
    • 并发清除:清除对象,可以和用户线程并发执行

img

由于垃圾回收线程可以和用户线程同时运行,也就是说它是并发的,那么它会对CPU的资源非常敏感,CMS默认启动的回收线程数是(CPU数量+3)/ 4,当CPU<4个时,并发回收是垃圾收集线程就不会少于25%,而且随着CPU减少而增加,这样会影响用户线程的执行。而且由于它是基于标记-清除算法的,那么就无法避免空间碎片的产生。CMS收集器无法处理浮动垃圾(Floating Garbage),可能出现“Concurrent Mode Failure”失败而导致另一次Full GC的产生。

​ 所谓浮动垃圾,在CMS并发清理阶段用户线程还在运行着,伴随程序运行自然还会有新的垃圾不断产生,这一部分垃圾出现在标记过程之后,CMS无法在当次收集中处理掉它们,只能留待下一次GC时再清理掉。

4. G1垃圾收集器

  • G1从整体上来看是基于标记-清除算法的,但是局部上基于复制算法。这样的好处是空间整合做的比较好,不会产生空间碎片

  • G1也是并发与并行的,充分利用多CPU、多核的硬件环境来缩短Stop the World的时间

  • G1还是分代收集的,但是是需要分代配合不同的垃圾收集器。因为G1中的垃圾收集器区域是分区的

运作流程:初始标记、并发标记、最终标记、筛选回收不会产生空间碎片,可以精确控制停顿

G1将整个堆分为大小相等的多个Rigion区域G1跟踪每个区域的垃圾大小,在后台维护一个优先级列表。每次根据允许的收集时间,优先回收价值最大的区域,以达到在有限时间内获取尽可能高的回收效率

三、产生OOM的原因

  • 文件描述符数目(fd)超限,可能的发生场景有:
    • 短时间内大量请求导致socket的fd数激增,大量(重复)打开文件等
  • 线程数超限
    • app内多线程使用不合理,多个不共享线程池的OKhttpclient等
  • 传统的java堆内存超限
  • 32位系统进程逻辑空间被占满导致OOM
  • 其他
  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值