首页 > 其他分享 >JVM 思考与总结

JVM 思考与总结

时间:2023-10-27 18:15:28浏览次数:29  
标签:总结 收集 JVM Eden Survivor GC 内存 思考 Minor

相关基础知识见:

深入理解 JVM -- 垃圾收集器与内存分配策略

 

新生代为什么需要两个 Survivor 区?

如果只有一个 Eden 区加一个 Survivor 区,那么 Minor GC 后 Eden 区还存活下来的对象复制到 Survivor 区。而 Survivor 区里的对象在这次 Minor GC 中,既有这次 GC 没活下来的,还有这次 GC 后活下来的,这时我们没有第二块 Survivor 区存放这块 Survivor 区上活下来的对象,那么就不能采取标记-复制,只能采取标记-清理算法,造成 Surviver 区内存碎片的产生。

如果有第二块 Survivor 区记为 S1,另一块记作 S0。那么一次 Minor GC 后,Eden 区和 S0 上存活下来的都复制到 S1 上,S0 和 Eden 清空,之后在 Eden 分配新对象;再下次 Minor GC,Eden 和 S1 上存活下来的就复制到空白的 S0 上,Eden 和 S1 清空,之后在 Eden 分配新对象........这样 S0 和 S1 轮换使用。

HotSpot虚拟机默认 Eden 和 Survivor 的大小比例是8∶1。

Minor GC 时会 stop the world 吗?

只要垃圾收集时会移动存活对象的做法都必须 Stop the world

现在的商用 Java 虚拟机大多都优先采用了 标记-复制 收集算法回收新生代,所以会 Stop the world

同理,多用于回收老年代的 标记-清除 算法(CMS)不需要 Stop the world,但会有内存碎片降低吞吐量;标记-整理 算法(Serial Old,Parallel Old)没有内存碎片,但需要 Stop the world

G1 都是 标记-复制 算法,优先回收收益最大的,把回收的 region 中存活下来的复制到空白的 region 里

Minor GC 什么时候触发?

新生代收集(Minor GC/Young GC):指目标只是新生代的垃圾收集。

HotSpot虚拟机默认Eden和Survivor的大小比例是8∶1,也即每次新生代中可用内存空间为整个新生代容量的90%(Eden的80%加上一个Survivor的10%,剩下 10% 是给第一次回收后复制仍然存活的对象的)。

大多数情况下,对象在新生代Eden区中分配。当Eden区没有足够空间进行分配时,虚拟机将发起 一次Minor GC。

什么是分配担保机制?

进行 Minor GC时有分配担保机制,GC 完之后剩的对象可能过多,一块 survivor 区放不下,这时就需要老年代来进行担保,担保失败可能 full GC

Full GC 什么时候触发?

整堆收集(Full GC):收集整个Java堆和方法区的垃圾收集。

  1. 大对象直接在老年代分配-但老年代连续空间放不下时:HotSpot虚拟机提供了-XX:PretenureSizeThreshold 参数,指定 大于该设置值 的对象 直接在老年代 分配,这样做的目的就是避免在Eden 区及两个Survivor区之间来回复制,产生大量的内存复制操作。
  2. 代码调用 System.gc() 显式触发
  3. 与上图中 Minor GC 时分配担保机制相关的:
    • 参数不允许担保失败。直接 Full GC
    • 老年代最大可用连续空间 小于 历次晋升到老年代对象的平均大小。直接 Full GC
    • 进行 Minor GC 中途发现老年代空间不够,即担保失败时。进行 Full GC

可以看出,老年代一般收集都是在 Full GC 中的,而触发了 Full GC 的条件,不论是大对象在老年代直接分配但放不下,还是担保失败。基本都是老年代几乎满了才会进行收集。

会单独回收老年代吗?Major GC

老年代收集(Major GC/Old GC):指目标只是老年代的垃圾收集。目前只有CMS收集器会有单独收集老年代的行为。

另外请注意“Major GC”这个说法现在有点混淆,在不同资料上常有不同所指, 读者需按上下文区分到底是指老年代的收集还是整堆收集。

标记-整理 的内存碎片有什么问题?

  • 没有内存碎片时,只要移动堆顶指针,按顺序分配。而内存碎片 会导致分配内存操作更加复杂,只能依赖更为复杂的内存分配器和内存访问器来解决。内存的访问是用户程序最频繁的操作,增加了内存访问的负担,降低了吞吐量;
  • 内存碎片严重时,即使剩余空间多,大对象也无法分配,而不得不提前触发一次Full GC。

吞吐量 和 垃圾收集停顿时间 不可兼得?

吞吐量 是处理器用于 运行用户代码的时间 与 处理器总消耗时间(用户代码时间+垃圾收集停顿时间) 的比值

垃圾收集停顿时间缩短 是以 牺牲吞吐量 和 新生代空间 为代价换取的:

  • 新生代空间大,那么一次收集耗时长,但是垃圾收集相对没那么频繁;
  • 新生代空间小,那么一次收集耗时更短,但是垃圾收集也更频繁,吞吐量降低。

另外采用的算法在这两者上的影响也是矛盾的:

  • 标记-清除 算法 不需要 Stop the world,但会有内存碎片,导致吞吐量下降。
  • 标记-整理 算法 没有内存碎片,但需要 Stop the world,增大了时延。

不同的垃圾收集器在这两个矛盾的目标之间有取舍:

关注吞吐量(标记-整理):

  • Parallel Scavenge:新生代收集器 标记-复制,多线程,提供了两个参数用于精确控制吞吐量:控制最大垃圾收集停顿时间的 MaxGCPauseMillis 间接影响吞吐量,以及直接设置吞吐量大小的GCTimeRatio。还有参数可以开启 自适应的调节策略可以自适应调节新生代大小 Eden 区比例等。
  • Parallel Old:Parallel Scavenge 的老年代版本,标记-整理

关注停顿时间:

  • CMS:以获取最短回收停顿时间为目标,老年代收集器,标记-清除,因此清除阶段可与用户线程并发,但要预留老年代空间给浮动垃圾
  • G1:用户可控制停顿时间。整体 标记-整理,局部 标记-复制。

JVM 内存越大越好吗?

回收大内存的Java堆,一次Full GC的停顿时间会非常长

 

标签:总结,收集,JVM,Eden,Survivor,GC,内存,思考,Minor
From: https://www.cnblogs.com/suBlog/p/17790297.html

相关文章

  • 第四章知识的完整性总结
    1.进程(Process):进程是独立运行的程序实例,具有各自的地址空间和资源。在Unix/Linux中,进程可以通过fork()或clone()系统调用创建。2.线程(Thread):线程是进程中的执行单元,共享进程的地址空间和资源,但有各自的栈和寄存器。线程可以通过pthread库来创建和管理。3.进程间通信(Inter-Pr......
  • 每日总结10.27
    今天通过在虚拟机上配置了Spark,使用SparkAPI编写一个独立应用程序,学习链接https://dblab.xmu.edu.cn/blog/4322/使用Maven对Scala独立应用程序进行编译打包完成了软件构造的作业,将生成的算式习题长期保存下来,采用了CSV形式存储    ......
  • 树剖小总结
    P2680[NOIP2015提高组]运输计划要求经过边的询问的最大值,和不经过边的询问的最大值,直接用线段树维护就行了。然后就是二分做法,比较合理。P4219[BJOI2014]大融合首先考虑暴力做法,随便钦定一个树根,然后维护子树size即可。每次连边,比如x作为y的父亲,那么x及其祖先的siz......
  • XML知识点总结
    1.xml1.1概述【理解】万维网联盟(W3C)万维网联盟(W3C)创建于1994年,又称W3C理事会。1994年10月在麻省理工学院计算机科学实验室成立。建立者:TimBerners-Lee(蒂姆·伯纳斯·李)。是Web技术领域最具权威和影响力的国际中立性技术标准机构。到目前为止,W3C已发布了200多项影响深远......
  • 代码随想录算法训练营第一天 | 977.有序数组的平方 ,209.长度最小的子数组 ,59.螺旋矩
    今日学习的文章链接和视频链接https://programmercarl.com/0977.有序数组的平方.htmlhttps://programmercarl.com/0209.长度最小的子数组.htmlhttps://programmercarl.com/0059.螺旋矩阵II.html977.有序数组的平方菜鸡刚开始只会暴力,记录一下双指针:varsortedSquares=......
  • C++的std::move与std::forward原理总结
    目录0、左值与右值的理解左值和右值的概念左值引用和右值引用1.std::move1.1函数原型1.2参数讨论1.3通用引用1.4返回值1.5std::move的常用例子1.5.1用于vector添加值1.5.2用于unique_ptr传递1.6再说转移对象控制权2.std::foward参考阅读大型的C++开源项目代码,基本......
  • 10月27号总结
    一、什么是JWTJWT(JSONWebToken)是一种用于在网络应用间传递信息的开放标准(RFC7519)。它以JSON格式存储被加密后的信息,通常用于验证和身份认证。这是token验证的一种令牌。叫身份验证令牌。在前后端分离的架构中常用。白话文理解:         在以前用cookie认证时候,会把......
  • # CSP-S 2023 总结
    A密码锁暴力枚举每一个锁可以到达的状态,集合并起来就OK。B消消乐蒙蔽,首先有一个直观的想法就是区间dp,\(dp_{l,r}\)表示区间\([l,r]\)可以消除到什么长度。然后突然意识到可以从每一个字符开头做一遍栈,如果为空就表示可以。思考到这里,脑子就短路了,实际上可以dp,每个点......
  • JVM 对象的创建
    目录对象的创建类加载分配内存内存分配的两种方式内存分配并发问题初始化零值设置对象头执行init方法对象的内存布局对象的访问定位句柄直接指针HotSpot虚拟机在Java堆中对象分配、布局和访问的全过程。对象的创建类加载虚拟机遇到一条new指令时,首先将去检查这个指令的......
  • 每日总结
    今日收获将操作系统的内容看完啦~也解决了之前的遗留问题;写完了软件构造的作业和软件设计作业;明天预计明天要稍稍准备一下普通话,打印准考证;复习那个比赛,周六校内选拔呀~加油呀~~继续复习软考......