JVM面试突击班2
JVM面试突击班2
对象被判定为不可达对象之后就“死”了吗
对象的生命周期

创建阶段
(1)为对象分配存储空间
(2)开始构造对象
(3)从超类到子类对static成员进行初始化
(4)超类成员变量按顺序初始化,递归调用超类的构造方法
(5)子类成员变量按顺序初始化,子类构造方法调用,并且一旦对象被创建,并被分派给某些变量赋值,这个对象的状态就切换到了应用阶段
应用阶段
(1)系统至少维护着对象的一个强引用(Strong Reference)
(2)所有对该对象的引用全部是强引用(除非我们显式地使用了:软引用(Soft Reference)、弱引用(Weak Reference)或虚引用(Phantom Reference))
引用的定义:
1.我们的数据类型必须是引用类型
2.我们这个类型的数据所存储的数据必须是另外一块内存的起始地址
[外链图片转存失败,源站可能有防盗链机制,建议将图片保存下来直接上传(img-zwiw3GKW-1691043052393)(https://fynotefile.oss-cn-zhangjiakou.aliyuncs.com/fynote/fyfile/1463/1650279430028/3900ed8910404854b5595e3c9979bb80.png)]
引用:
1.强引用
JVM内存管理器从根引用集合(Root Set)出发遍寻堆中所有到达对象的路径。当到达某对象的任意路径都不含有引用对象时,对这个对象的引用就被称为强引用
2.软引用
软引用是用来描述一些还有用但是非必须的对象。对于软引用关联的对象,在系统将于发生内存溢出异常之前,将会把这些对象列进回收范围中进行二次回收。
(当你去处理占用内存较大的对象 并且生命周期比较长的,不是频繁使用的)
问题:软引用可能会降低应用的运行效率与性能。比如:软引用指向的对象如果初始化很耗时,或者这个对象在进行使用的时候被第三方施加了我们未知的操作。
3.弱引用
弱引用(Weak Reference)对象与软引用对象的最大不同就在于:GC在进行回收时,需要通过算法检查是否回收软引用对象,而对于Weak引用对象, GC总是进行回收。因此Weak引用对象会更容易、更快被GC回收
4.虚引用
也叫幽灵引用和幻影引用,为一个对象设置虚引用关联的唯一目的就是能在这个对象被回收时收到一个系统通知。也就是说,如果一个对象被设置上了一个虚引用,实际上跟没有设置引用没有任何的区别
软引用代码Demo:
public class SoftReferenceDemo {public static void main(String[] args) {//。。。一堆业务代码Worker a = new Worker();
//。。业务代码使用到了我们的Worker实例// 使用完了a,将它设置为soft 引用类型,并且释放强引用;SoftReference sr = new SoftReference(a);a = null;
//这个时候他是有可能执行一次GC的System.gc();// 下次使用时if (sr != null) {a = (Worker) sr.get();System.out.println(a );} else {// GC由于内存资源不足,可能系统已回收了a的软引用,// 因此需要重新装载。a = new Worker();sr = new SoftReference(a);}}}
弱引用代码Demo:
public class WeakReferenceDemo {public static void main(String[] args) throws InterruptedException {//100M的缓存数据byte[] cacheData = new byte[100 * 1024 * 1024];//将缓存数据用软引用持有WeakReference<byte[]> cacheRef = new WeakReference<>(cacheData);System.out.println("第一次GC前" + cacheData);System.out.println("第一次GC前" + cacheRef.get());//进行一次GC后查看对象的回收情况System.gc();//因为我们不确定我们的System什么时候GCThread.sleep(1000);System.out.println("第一次GC后" + cacheData);System.out.println("第一次GC后" + cacheRef.get());//将缓存数据的强引用去除cacheData = null;System.gc(); //默认通知一次Full GC//等待GCThread.sleep(500);System.out.println("第二次GC后" + cacheData);System.out.println("第二次GC后" + cacheRef.get());// // 弱引用Map
// WeakHashMap<String, String> whm = new WeakHashMap<String,String>();}
}
虚引用代码Demo:
public class PhantomReferenceDemo {public static void main(String[] args) throws InterruptedException {Object value = new Object();ReferenceQueue<Object> referenceQueue = new ReferenceQueue<>();Thread thread = new Thread(() -> {try {int cnt = 0;WeakReference<byte[]> k;while ((k = (WeakReference) referenceQueue.remove()) != null) {System.out.println((cnt++) + "回收了:" + k);}} catch (InterruptedException e) {//结束循环}});thread.setDaemon(true);thread.start();Map<Object, Object> map = new HashMap<>();for (int i = 0; i < 10000; i++) {byte[] bytes = new byte[1024 * 1024];WeakReference<byte[]> weakReference = new WeakReference<byte[]>(bytes, referenceQueue);map.put(weakReference, value);}System.out.println("map.size->" + map.size());}
}
finalize方法代码Demo:
public class Finalize {private static Finalize save_hook = null;//类变量public void isAlive() {System.out.println("我还活着");}@Overridepublic void finalize() {System.out.println("finalize方法被执行");Finalize.save_hook = this;}public static void main(String[] args) throws InterruptedException {save_hook = new Finalize();//对象//对象第一次拯救自己save_hook = null;System.gc();//暂停0.5秒等待他Thread.sleep(500);if (save_hook != null) {save_hook.isAlive();} else {System.out.println("好了,现在我死了");}//对象第二次拯救自己save_hook = null;System.gc();//暂停0.5秒等待他Thread.sleep(500);if (save_hook != null) {save_hook.isAlive();} else {System.out.println("我终于死亡了");}}
}
不可见阶段
不可见阶段的对象在虚拟机的对象根引用集合中再也找不到直接或者间接的强引用,最常见的就是线程或者函数中的临时变量。程序不在持有对象的强引用。 (但是某些类的静态变量或者JNI是有可能持有的 )
不可达阶段
指对象不再被任何强引用持有,GC发现该对象已经不可达。
引用 - > 对象
如何确定一个对象是垃圾?
要想进行垃圾回收,得先知道什么样的对象是垃圾。
- 引用计数法 循环引用
对于某个对象而言,只要应用程序中持有该对象的引用,就说明该对象不是垃圾,如果一个对象没有任何指针对其引用,它就是垃圾。
弊端:如果AB相互持有引用,导致永远不能被回收。 循环引用 内存泄露 -->内存溢出

- 可达性分析/根搜索算法
通过GC Root的引用,开始向下寻找,看某个对象是否可达
[外链图片转存失败,源站可能有防盗链机制,建议将图片保存下来直接上传(img-PhMt8Ze1-1691043052394)(file://E:/%E6%A1%8C%E9%9D%A2/yzt/%E7%AC%94%E8%AE%B0%E8%AF%BE%E4%BB%B6/JVM/3%E5%A4%A9JVM%E8%AE%AD%E7%BB%83%E8%90%A5/%E8%B5%84%E6%96%99+%E7%AC%94%E8%AE%B0/images/64.png?lastModify=1646659177)]
能作为GC Root:类加载器、Thread、虚拟机栈的本地变量表、static成员、常量引用、本地方法栈的变量等。
虚拟机栈(栈帧中的本地变量表)中引用的对象。
方法区中类静态属性引用的对象。
方法区中常量引用的对象。
本地方法栈中JNI(即一般说的Native方法)引用的对象。
垃圾收集算法
已经能够确定一个对象为垃圾之后,接下来要考虑的就是回收,怎么回收呢?得要有对应的算法,下面介绍常见的垃圾回收算法。高效 健壮
标记-清除(Mark-Sweep)
- 标记
找出内存中所有的存活对象,并且把它们标记出来
[外链图片转存失败,源站可能有防盗链机制,建议将图片保存下来直接上传(img-Dhjmltab-1691043052395)(file://E:\桌面\yzt\笔记课件\JVM\3天JVM训练营\资料+笔记\images\25.png?lastModify=1646720640)]
- 清除
清除掉被标记需要回收的对象,释放出对应的内存空间
[外链图片转存失败,源站可能有防盗链机制,建议将图片保存下来直接上传(img-8GNPP7eo-1691043052396)(file://E:\桌面\yzt\笔记课件\JVM\3天JVM训练营\资料+笔记\images\26.png?lastModify=1646720640)][外链图片转存失败,源站可能有防盗链机制,建议将图片保存下来直接上传(img-XDvs6uy2-1691043052396)(https://fynotefile.oss-cn-zhangjiakou.aliyuncs.com/fynote/1463/1646137467048/5beab74efce64c5897d16f39db5e58f3.png)]
缺点
标记清除之后会产生大量不连续的内存碎片,空间碎片太多可能会导致以后在程
序运行过程中需要分配较大对象时,无法找到足够的连续内存而不得不提前触发另一次垃圾收集动作。
(1)标记和清除两个过程都比较耗时,效率不高
(2)会产生大量不连续的内存碎片,空间碎片太多可能会导致以后在程序运行过程中需要分配较大对象时,无法找到足够的连续内存而不得不提前触发另一次垃圾收集动作。
标记清除算法的衍生规则之分配(动态分区分配策略)
首次适应算法(Fisrt-fit)
首次适应算法(Fisrt-fit)就是在遍历空闲链表的时候,一旦发现有大小大于等于需要的大小之后,就立即把该块分配给对象,并立即返回。
最佳适应算法(Best-fit)
最佳适应算法(Best-fit)就是在遍历空闲链表的时候,返回刚好等于需要大小的块。
最差适应算法(Worst-fit)
最差适应算法(Worst-fit)就是在遍历空闲链表的时候,找出空闲链表中最大的分块,将其分割给申请的对象,其目的就是使得分割后分块的最大化,以便下次好分配,不过这种分配算法很容易产生很多很小的分块,这些分块也不能被使用
什么是STW(stop the world)?
Stop-The-World 简称 STW
是在垃圾回收算法执行过程中,将jvm内存冻结,停顿的一种状态,在Stw情况下,容易出现两种现象:
该回收的对象没有被回收
不该回收的对象被回收了
在STW状态下,所有的线程都是停止运行的 - >垃圾回收线程除外
当STW发生时,出了GC所需要的线程,其他的线程都将停止工作,中断了的线程知道GC线程结束才会继续任务
STW是不可避免的,垃圾回收算法的执行一定会出现STW,而我们最好的解决办法就是减少停顿的时间
GC各种算法的优化重点就是为了减少STW,这也是JVM调优的重点。
标记-复制(Mark-Copying)
将内存划分为两块相等的区域,每次只使用其中一块,如下图所示:
[外链图片转存失败,源站可能有防盗链机制,建议将图片保存下来直接上传(img-5vmyhM0q-1691043052396)(file://E:\桌面\yzt\笔记课件\JVM\3天JVM训练营\资料+笔记\images\27.png?lastModify=1646720640)][外链图片转存失败,源站可能有防盗链机制,建议将图片保存下来直接上传(img-BBFjF1XJ-1691043052397)(https://fynotefile.oss-cn-zhangjiakou.aliyuncs.com/fynote/1463/1646137467048/44cbc243638f4544917f0aa44e440c82.png)]
当其中一块内存使用完了,就将还存活的对象复制到另外一块上面,然后把已经使用过的内存空间一次清除掉。
[外链图片转存失败,源站可能有防盗链机制,建议将图片保存下来直接上传(img-LsB0KV8W-1691043052397)(file://E:\桌面\yzt\笔记课件\JVM\3天JVM训练营\资料+笔记\images\28.png?lastModify=1646720640)][外链图片转存失败,源站可能有防盗链机制,建议将图片保存下来直接上传(img-M4VX5JCx-1691043052397)(https://fynotefile.oss-cn-zhangjiakou.aliyuncs.com/fynote/1463/1646137467048/b81f9e21abd84b0aaa102f27c4007986.png)]
缺点:空间利用率降低。
标记-整理(Mark-Compact)
复制收集算法在对象存活率较高时就要进行较多的复制操作,效率将会变低。更关键的是,如果不想浪费50%的空间,就需要有额外的空间进行分配担保,以应对被使用的内存中所有对象都有100%存活的极端情况,所以老年代一般不能直接选用这种算法。
标记过程仍然与"标记-清除"算法一样,但是后续步骤不是直接对可回收对象进行清理,而是让所有存活的对象都向一端移动,然后直接清理掉端边界以外的内存。
其实上述过程相对"复制算法"来讲,少了一个"保留区"
[外链图片转存失败,源站可能有防盗链机制,建议将图片保存下来直接上传(img-u0NeLjuW-1691043052398)(file://E:\桌面\yzt\笔记课件\JVM\3天JVM训练营\资料+笔记\images\25.png?lastModify=1646720640)][外链图片转存失败,源站可能有防盗链机制,建议将图片保存下来直接上传(img-foAjps2M-1691043052398)(https://fynotefile.oss-cn-zhangjiakou.aliyuncs.com/fynote/1463/1646137467048/331b1e9000d34b5093ed5b60a24e0402.png)]
让所有存活的对象都向一端移动,清理掉边界意外的内存。
[外链图片转存失败,源站可能有防盗链机制,建议将图片保存下来直接上传(img-AhU6RCfJ-1691043052398)(file://E:\桌面\yzt\笔记课件\JVM\3天JVM训练营\资料+笔记\images\29.png?lastModify=1646720640)]
分代收集算法
既然上面介绍了3中垃圾收集算法,那么在堆内存中到底用哪一个呢?
Young区:复制算法(对象在被分配之后,可能生命周期比较短,Young区复制效率比较高)
Old区:标记清除或标记整理(Old区对象存活时间比较长,复制来复制去没必要,不如做个标记再清理)
其他算法
增量回收算法:
垃圾回收其实就是对不需要的内存对象进行清理,前面提到的GC算法,无论哪种,基本都是过一段时间对所有的内存空间对象进行一次大扫除。 这种的GC缺点是一旦开始启动,管理程序可能就停止了,表现就是可能好多程序都没响应。可在服务端,这是大忌。增量式(incremental)出现就是解决这个问题的,这种垃圾回收采用和应用程序交替进行的方式来工作,表现就像是GC在不断的定时迭加操作。从而尽量减轻应用程序的停止时间,这就是增量式回收的特点。
在增量式回收里,比较容易接触到的就是三色标记算法。
三色标记
在并发标记的过程中,因为标记期间应用线程还在继续跑,对象间的引用可能发生变化,多标和漏标的情况就有可能发生。这里引入“三色标记”来给大家解释下,把Gc roots可达性分析遍历对象过程中遇到的对象, 按照“是否访问过”这个条件标记成以下三种颜色:
黑色:
表示对象已经被垃圾收集器访问过, 且这个对象的所有引用都已经扫描过。 黑色的对象代表已经扫描过, 它是安全存活的, 如果有其他对象引用指向了黑色对象, 无须重新扫描一遍。 黑色对象不可能直接(不经过灰色对象) 指向某个白色对象。
2.将GC Roots 直接引用到的对象 挪到 【灰色集合】中;
3.从灰色集合中获取对象:
- 将本对象 引用到的 其他对象 全部挪到 【灰色集合】中;
- 将本对象 挪到 【黑色集合】里面。
重复步骤3.4,直至【灰色集合】为空时结束。
结束后,仍在【白色集合】的对象即为GC Roots 不可达,可以进行回收

多标-浮动垃圾
在并发标记过程中,如果由于方法运行结束导致部分局部变量(gcroot)被销毁,这个gc root引用的对象之前又被扫描过 (被标记为非垃圾对象),那么本轮GC不会回收这部分内存。这部分本应该回收但是没有回收到的内存,被称之为“浮动 垃圾”。浮动垃圾并不会影响垃圾回收的正确性,只是需要等到下一轮垃圾回收中才被清除。另外,针对并发标记(还有并发清理)开始后产生的新对象,通常的做法是直接全部当成黑色,本轮不会进行清除。这部分 对象期间可能也会变为垃圾,这也算是浮动垃圾的一部分。
漏标-读写屏障
漏标只有同时满足以下两个条件时才会发生:
条件一:灰色对象 断开了 白色对象的引用;即灰色对象 原来成员变量的引用 发生了变化。条件二:黑色对象 重新引用了 该白色对象;即黑色对象 成员变量增加了 新的引用。
漏标会导致被引用的对象被当成垃圾误删除,这是严重bug,必须解决,有两种解决方案: 增量更新(Incremental Update) 和原始快照(Snapshot At The Beginning,SATB) 。
增量更新就是当黑色对象插入新的指向白色对象的引用关系时, 就将这个新插入的引用记录下来, 等并发扫描结束之后, 再将这些记录过的引用关系中的黑色对象为根, 重新扫描一次。 这可以简化理解为, 黑色对象一旦新插入了指向白色对象的引用之后, 它就变回灰色对象了。
原始快照就是当灰色对象要删除指向白色对象的引用关系时, 就将这个要删除的引用记录下来, 在并发扫描结束之后, 再将这些记录过的引用关系中的灰色对象为根, 重新扫描一次,这样就能扫描到白色的对象,将白色对象直接标记为黑色(目的就是让这种对象在本轮gc清理中能存活下来,待下一轮gc的时候重新扫描,这个对象也有可能是浮动垃圾)
以上无论是对引用关系记录的插入还是删除, 虚拟机的记录操作都是通过写屏障实现的。
写屏障实现原始快照(SATB): 当对象B的成员变量的引用发生变化时,比如引用消失(a.b.d = null),我们可以利用写屏障,将B原来成员变量的引用对象D记录下来:
写屏障实现增量更新: 当对象A的成员变量的引用发生变化时,比如新增引用(a.d = d),我们可以利用写屏障,将A新的成员变量引用对象D 记录下来:
垃圾收集器
如果说收集算法是内存回收的方法论,那么垃圾收集器就是内存回收的具体实现。
[外链图片转存失败,源站可能有防盗链机制,建议将图片保存下来直接上传(img-wLbYuq97-1691043052399)(file://E:\桌面\yzt\笔记课件\JVM\3天JVM训练营\资料+笔记\images\30.png?lastModify=1646736013)]
- Serial
Serial收集器是最基本、发展历史最悠久的收集器,曾经(在JDK1.3.1之前)是虚拟机新生代收集的唯一选择。
它是一种单线程收集器,不仅仅意味着它只会使用一个CPU或者一条收集线程去完成垃圾收集工作,更重要的是其在进行垃圾收集的时候需要暂停其他线程。
优点:简单高效,拥有很高的单线程收集效率
缺点:收集过程需要暂停所有线程
算法:复制算法
适用范围:新生代
应用:Client模式下的默认新生代收集器
[外链图片转存失败,源站可能有防盗链机制,建议将图片保存下来直接上传(img-Gzasijoi-1691043052399)(file://E:\桌面\yzt\笔记课件\JVM\3天JVM训练营\资料+笔记\images\31.png?lastModify=1646736013)]
- Serial Old
Serial Old收集器是Serial收集器的老年代版本,也是一个单线程收集器,不同的是采用"标记-整理算法",运行过程和Serial收集器一样。
[外链图片转存失败,源站可能有防盗链机制,建议将图片保存下来直接上传(img-wS3WqK7d-1691043052400)(file://E:\桌面\yzt\笔记课件\JVM\3天JVM训练营\资料+笔记\images\32.png?lastModify=1646736013)]
- ParNew
可以把这个收集器理解为Serial收集器的多线程版本。
优点:在多CPU时,比Serial效率高。
缺点:收集过程暂停所有应用程序线程,单CPU时比Serial效率差。
算法:复制算法
适用范围:新生代
应用:运行在Server模式下的虚拟机中首选的新生代收集器
[外链图片转存失败,源站可能有防盗链机制,建议将图片保存下来直接上传(img-e6AcUdZX-1691043052401)(file://E:\桌面\yzt\笔记课件\JVM\3天JVM训练营\资料+笔记\images\33.png?lastModify=1646736013)]
- Parallel Scavenge
Parallel Scavenge收集器是一个新生代收集器,它也是使用复制算法的收集器,又是并行的多线程收集器,看上去和ParNew一样,但是Parallel Scanvenge更关注系统的吞吐量。
吞吐量=运行用户代码的时间/(运行用户代码的时间+垃圾收集时间)
比如虚拟机总共运行了100分钟,垃圾收集时间用了1分钟,吞吐量=(100-1)/100=99%。
若吞吐量越大,意味着垃圾收集的时间越短,则用户代码可以充分利用CPU资源,尽快完成程序的运算任务。
-XX:MaxGCPauseMillis控制最大的垃圾收集停顿时间,
-XX:GCRatio直接设置吞吐量的大小。
- Parallel Old
Parallel Old收集器是Parallel Scavenge收集器的老年代版本,使用多线程和标记-整理算法进行垃圾回收,也是更加关注系统的吞吐量。
- CMS
官网: https://docs.oracle.com/javase/8/docs/technotes/guides/vm/gctuning/cms.html#concurrent_mark_sweep_cms_collectorCMS(Concurrent Mark Sweep)收集器是一种以获取
最短回收停顿时间为目标的收集器。采用的是"标记-清除算法",整个过程分为4步
(1)初始标记 CMS initial mark 标记GC Roots直接关联对象,不用Tracing,速度很快
(2)并发标记 CMS concurrent mark 进行GC Roots Tracing
(3)重新标记 CMS remark 修改并发标记因用户程序变动的内容
(4)并发清除 CMS concurrent sweep 清除不可达对象回收空间,同时有新垃圾产生,留着下次清理称为浮动垃圾
由于整个过程中,并发标记和并发清除,收集器线程可以与用户线程一起工作,所以总体上来说,CMS收集器的内存回收过程是与用户线程一起并发地执行的。
[外链图片转存失败,源站可能有防盗链机制,建议将图片保存下来直接上传(img-fBwaGKey-1691043052403)(file://E:\桌面\yzt\笔记课件\JVM\3天JVM训练营\资料+笔记\images\34.png?lastModify=1646736013)]
优点:并发收集、低停顿
缺点:产生大量空间碎片、并发阶段会降低吞吐量
什么是记忆集?
当我们进行young gc时,我们的gc roots除了常见的栈引用、静态变量、常量、锁对象、class对象这些常见的之外,如果 老年代有对象引用了我们的新生代对象 ,那么老年代的对象也应该加入gc roots的范围中,但是如果每次进行young gc我们都需要扫描一次老年代的话,那我们进行垃圾回收的代价实在是太大了,因此我们引入了一种叫做记忆集的抽象数据结构来记录这种引用关系。
记忆集是一种用于记录从非收集区域指向收集区域的指针集合的数据结构。
如果我们不考虑效率和成本问题,我们可以用一个数组存储所有有指针指向新生代的老年代对象。但是如果这样的话我们维护成本就很好,打个比方,假如所有的老年代对象都有指针指向了新生代,那么我们需要维护整个老年代大小的记忆集,毫无疑问这种方法是不可取的。因此我们引入了卡表的数据结构
卡表
记忆集是我们针对于跨代引用问题提出的思想,而卡表则是针对于该种思想的具体实现。(可以理解为记忆集是结构,卡表是实现类)
[1字节,00001000,1字节,1字节]
在hotspot虚拟机中,卡表是一个字节数组,数组的每一项对应着内存中的某一块连续地址的区域,如果该区域中有引用指向了待回收区域的对象,卡表数组对应的元素将被置为1,没有则置为0;
(1) 卡表是使用一个字节数组实现:CARD_TABLE[],每个元素对应着其标识的内存区域一块特定大小的内存块,称为"卡页"。hotSpot使用的卡页是2^9大小,即512字节
(2) 一个卡页中可包含多个对象,只要有一个对象的字段存在跨代指针,其对应的卡表的元素标识就变成1,表示该元素变脏,否则为0。GC时,只要筛选本收集区的卡表中变脏的元素加入GC Roots里。
卡表的使用图例

并发标记的时候,A对象发生了所在的引用发生了变化,所以A对象所在的块被标记为脏卡

继续往下到了重新标记阶段,修改对象的引用,同时清除脏卡标记。

卡表其他作用:
老年代识别新生代的时候
对应的card table被标识为相应的值(card table中是一个byte,有八位,约定好每一位的含义就可区分哪个是引用新生代,哪个是并发标记阶段修改过的)
- G1(Garbage-First)
官网: https://docs.oracle.com/javase/8/docs/technotes/guides/vm/gctuning/g1_gc.html#garbage_first_garbage_collection**使用G1收集器时,Java堆的内存布局与就与其他收集器有很大差别,它将整个Java堆划分为多个大小相等的独立区域(Region),虽然还保留有新生代和老年代的概念,但新生代和老年代不再是物理隔离的了,它们都是一部分Region(不需要连续)的集合。 **
每个Region大小都是一样的,可以是1M到32M之间的数值,但是必须保证是2的n次幂
如果对象太大,一个Region放不下[超过Region大小的50%],那么就会直接放到H中
设置Region大小:-XX:G1HeapRegionSize=M
所谓Garbage-Frist,其实就是优先回收垃圾最多的Region区域
(1)分代收集(仍然保留了分代的概念) (2)空间整合(整体上属于“标记-整理”算法,不会导致空间碎片) (3)可预测的停顿(比CMS更先进的地方在于能让使用者明确指定一个长度为M毫秒的时间片段内,消耗在垃圾收集上的时间不得超过N毫秒)
[外链图片转存失败,源站可能有防盗链机制,建议将图片保存下来直接上传(img-nqSjHkRk-1691043052413)(file://E:\桌面\yzt\笔记课件\JVM\3天JVM训练营\资料+笔记\images\35.png?lastModify=1646736013)]
工作过程可以分为如下几步
初始标记(Initial Marking) 标记以下GC Roots能够关联的对象,并且修改TAMS的值,需要暂停用户线程
并发标记(Concurrent Marking) 从GC Roots进行可达性分析,找出存活的对象,与用户线程并发执行
最终标记(Final Marking) 修正在并发标记阶段因为用户程序的并发执行导致变动的数据,需暂停用户线程
筛选回收(Live Data Counting and Evacuation) 对各个Region的回收价值和成本进行排序,根据用户所期望的GC停顿时间制定回收计划
[外链图片转存失败,源站可能有防盗链机制,建议将图片保存下来直接上传(img-TidJQnXA-1691043052417)(file://E:\桌面\yzt\笔记课件\JVM\3天JVM训练营\资料+笔记\images\36.png?lastModify=1646736013)]
- ZGC
官网: https://docs.oracle.com/en/java/javase/11/gctuning/z-garbage-collector1.html#GUID-A5A42691-095E-47BA-B6DC-FB4E5FAA43D0JDK11新引入的ZGC收集器,不管是物理上还是逻辑上,ZGC中已经不存在新老年代的概念了
会分为一个个page,当进行GC操作时会对page进行压缩,因此没有碎片问题
只能在64位的linux上使用,目前用得还比较少
(1)可以达到10ms以内的停顿时间要求
(2)支持TB级别的内存
(3)堆内存变大后停顿时间还是在10ms以内
相关文章:
JVM面试突击班2
JVM面试突击班2 对象被判定为不可达对象之后就“死”了吗 对象的生命周期 创建阶段 (1)为对象分配存储空间 (2)开始构造对象 (3)从超类到子类对static成员进行初始化 (4)超类成…...
【80天学习完《深入理解计算机系统》】第二天 2.2 整数的表示【有符号数,无符号数,符号数的扩展,有无符号数的转变】
专注 效率 记忆 预习 笔记 复习 做题 欢迎观看我的博客,如有问题交流,欢迎评论区留言,一定尽快回复!(大家可以去看我的专栏,是所有文章的目录) 文章字体风格: 红色文字表示&#…...
基于 CentOS 7 构建 LVS-DR 群集以及配置nginx负载均衡
目录 一、基于 CentOS 7 构建 LVS-DR 群集 1、前期准备 1、关闭防火墙 2、安装ifconfig 3、准备四台虚拟机 2、在DS上 2.1、配置LVS虚拟IP 2.2、手工执行配置添加LVS服务并增加两台RS 2.3、查看配置 3、在RS端(第三台、第四台) 上 3.1、配置W…...
golang trace view 视图详解
大家好,我是蓝胖子,在golang中可以使用go pprof的工具对golang程序进行性能分析,其中通过go trace 命令生成的trace view视图对于我们分析系统延迟十分有帮助,鉴于当前对trace view视图的介绍还是很少,在粗略的看过tra…...
zju代码题:4-6
一 分段函数算水费 #include <stdio.h>int main() {/*** 定义两个* 定义浮点型变量* y:水费* x:用水的吨数* */double x, y;printf("Enter x(x>=0):\n"...
数据链路层概述
数据传输过程如下: 数据包按上述过程传输,详见(计算机网络概述三)。在分析数据链路层时可以假象成其沿着水平传播。 这三段链路层的传播方式可能会有所不同。 基本概念: 链路:指一个节点到相邻节点的一段物…...
Python代码使用技巧汇总:提升你的编程技能
各位程序员朋友们,今天我要跟大家分享一些关于Python代码的最佳使用技巧,这些技巧可以帮助你们成为更专业且高效的程序员。不管你是刚刚入门还是已经有一些经验,这些技巧都能够为你提供实际操作价值。 一、合理使用Python的数据结构和算法&am…...
Ae 效果:CC Spotlight
透视/CC Spotlight Perspective/CC Spotlight CC Spotlight(CC 聚光灯) 主要用途是创建和控制逼真的聚光灯效果。通过调整这些属性,可以模拟出各种不同的照明环境和效果,比如舞台照明、日出日落、特定的颜色照明等。 ◆ ◆ ◆ 效…...
如何在页面中嵌入音频和视频?
聚沙成塔每天进步一点点 ⭐ 专栏简介⭐ 嵌入音频⭐ 嵌入视频⭐ 写在最后 ⭐ 专栏简介 前端入门之旅:探索Web开发的奇妙世界 记得点击上方或者右侧链接订阅本专栏哦 几何带你启航前端之旅 欢迎来到前端入门之旅!这个专栏是为那些对Web开发感兴趣、刚刚踏…...
Unity 中检测射线穿过的所有的物体
在开发中 有个需求,射线要检测所有穿过的物体。 代码如下: using UnityEngine;public class HitCollider : MonoBehaviour {public float raycastDistance Mathf.Infinity;// Update is called once per framevoid Update(){Ray ray Camera.main.Scre…...
LeetCode 29题:两数相除
题目 给你两个整数,被除数 dividend 和除数 divisor。将两数相除,要求 不使用 乘法、除法和取余运算。 整数除法应该向零截断,也就是截去(truncate)其小数部分。例如,8.345 将被截断为 8 ,-2.…...
Axure RP9中使用Echarts示例
目录 在Axure中拖入一个矩形框,并命名tes 进入Echarts官网示例页面https://echarts.apache.org/examples/zh/index.html 选择自己需要的图表,修改数据,并复制左侧js代码 把上面复制的代码替换下方的option{}; javascript: var script docum…...
利用Jmeter做接口测试全流程分析
利用Jmeter做接口测试怎么做呢?过程真的是超级简单。 明白了原理以后,把零碎的知识点填充进去就可以了。这篇文章就来介绍一下如何利用Jmeter做接口测试的流程,主要针对的是功能测试。暂不涉及到自动化测试和性能测试的内容。 一把来说&…...
超级浏览器与指纹浏览器:功能与特点的比较
导语:随着互联网的快速发展,隐私和安全问题日益受到关注。在这个背景下,超级浏览器和指纹浏览器作为定制化浏览器的两个重要类型,各自具有独特的功能和特点。本文将对超级浏览器和指纹浏览器进行比较,帮助读者更好地理…...
云端同步、高效无界:5款免费的跨平台思维导图软件推荐!
思维导图是一种以图形化方式表示思想、概念或任务的方法,可以帮助用户梳理思维、提高记忆和理解。在工作中,思维导图可以用于会议记录、任务规划、项目管理等,帮助提高工作效率和团队协作能力;在学习中,思维导图可以用…...
OpenAI允许网站阻止其网络爬虫;谷歌推出类似Grammarly的语法检查功能
🦉 AI新闻 🚀 OpenAI推出新功能,允许网站阻止其网络爬虫抓取数据训练GPT模型 摘要:OpenAI最近推出了一个新功能,允许网站阻止其网络爬虫从其网站上抓取数据训练GPT模型。该功能通过在网站的Robots.txt文件中禁止GPTB…...
SpringBoot操作Jedis
SpringBoot操作Jedis 1、pom依赖 <?xml version"1.0" encoding"UTF-8"?> <project xmlns"http://maven.apache.org/POM/4.0.0" xmlns:xsi"http://www.w3.org/2001/XMLSchema-instance"xsi:schemaLocation"http://ma…...
实现静态资源访问的几种方法
什么是静态资源? 静态资源是指在服务器端存储的不会变化的文件,如HTML、CSS、JavaScript、图片、音频、视频等文件。这些文件一般不包含动态内容,每次请求时返回的内容都是固定的。 为什么要使用静态资源? 提升网站性能…...
chrome 下 autocomplete=off (禁止记住密码)不起作用解决方案
chrome 下 autocompleteoff (禁止记住密码)不起作用解决方案: 不知道是否是CHROME一个BUG,按说不应该,但事实它确实存在。 因时间关系,懒得查阅官方资料,这类问题解锁容易,思路如下: 初始化设置…...
设计模式-简单工厂模式(静态工厂模式)java实现
介绍 简单工厂模式根据所提供的参数数据返回几个可能类中的一个类的实例。通常返回的类都有一个公共的父类和公共的方法。 意图 提供一个类,负责根据一定的条件创建某一具体类的实例。同时使用工厂模式也是为了隐藏创建对象的过程 角色及其职责 (1)工厂(Creator…...
SkyWalking 10.2.0 SWCK 配置过程
SkyWalking 10.2.0 & SWCK 配置过程 skywalking oap-server & ui 使用Docker安装在K8S集群以外,K8S集群中的微服务使用initContainer按命名空间将skywalking-java-agent注入到业务容器中。 SWCK有整套的解决方案,全安装在K8S群集中。 具体可参…...
Qt/C++开发监控GB28181系统/取流协议/同时支持udp/tcp被动/tcp主动
一、前言说明 在2011版本的gb28181协议中,拉取视频流只要求udp方式,从2016开始要求新增支持tcp被动和tcp主动两种方式,udp理论上会丢包的,所以实际使用过程可能会出现画面花屏的情况,而tcp肯定不丢包,起码…...
从深圳崛起的“机器之眼”:赴港乐动机器人的万亿赛道赶考路
进入2025年以来,尽管围绕人形机器人、具身智能等机器人赛道的质疑声不断,但全球市场热度依然高涨,入局者持续增加。 以国内市场为例,天眼查专业版数据显示,截至5月底,我国现存在业、存续状态的机器人相关企…...
【论文笔记】若干矿井粉尘检测算法概述
总的来说,传统机器学习、传统机器学习与深度学习的结合、LSTM等算法所需要的数据集来源于矿井传感器测量的粉尘浓度,通过建立回归模型来预测未来矿井的粉尘浓度。传统机器学习算法性能易受数据中极端值的影响。YOLO等计算机视觉算法所需要的数据集来源于…...
Java-41 深入浅出 Spring - 声明式事务的支持 事务配置 XML模式 XML+注解模式
点一下关注吧!!!非常感谢!!持续更新!!! 🚀 AI篇持续更新中!(长期更新) 目前2025年06月05日更新到: AI炼丹日志-28 - Aud…...
高防服务器能够抵御哪些网络攻击呢?
高防服务器作为一种有着高度防御能力的服务器,可以帮助网站应对分布式拒绝服务攻击,有效识别和清理一些恶意的网络流量,为用户提供安全且稳定的网络环境,那么,高防服务器一般都可以抵御哪些网络攻击呢?下面…...
根据万维钢·精英日课6的内容,使用AI(2025)可以参考以下方法:
根据万维钢精英日课6的内容,使用AI(2025)可以参考以下方法: 四个洞见 模型已经比人聪明:以ChatGPT o3为代表的AI非常强大,能运用高级理论解释道理、引用最新学术论文,生成对顶尖科学家都有用的…...
Maven 概述、安装、配置、仓库、私服详解
目录 1、Maven 概述 1.1 Maven 的定义 1.2 Maven 解决的问题 1.3 Maven 的核心特性与优势 2、Maven 安装 2.1 下载 Maven 2.2 安装配置 Maven 2.3 测试安装 2.4 修改 Maven 本地仓库的默认路径 3、Maven 配置 3.1 配置本地仓库 3.2 配置 JDK 3.3 IDEA 配置本地 Ma…...
dify打造数据可视化图表
一、概述 在日常工作和学习中,我们经常需要和数据打交道。无论是分析报告、项目展示,还是简单的数据洞察,一个清晰直观的图表,往往能胜过千言万语。 一款能让数据可视化变得超级简单的 MCP Server,由蚂蚁集团 AntV 团队…...
LLMs 系列实操科普(1)
写在前面: 本期内容我们继续 Andrej Karpathy 的《How I use LLMs》讲座内容,原视频时长 ~130 分钟,以实操演示主流的一些 LLMs 的使用,由于涉及到实操,实际上并不适合以文字整理,但还是决定尽量整理一份笔…...
