做网站上海公司,做公司网站的必要性,澄海玩具网站建设公司,广东阳江网络问政平台说一下 JVM 有哪些垃圾回收器#xff1f; 如果说垃圾收集算法是内存回收的方法论#xff0c;那么垃圾收集器就是内存回收的具体实现。下图展示了 7 种作用于不同分代的收集器#xff0c;其中用于回收新生代的收集器包括 Serial 、 PraNew 、 Parallel Scavenge #xf… 说一下 JVM 有哪些垃圾回收器 如果说垃圾收集算法是内存回收的方法论那么垃圾收集器就是内存回收的具体实现。下图展示了 7 种作用于不同分代的收集器其中用于回收新生代的收集器包括 Serial 、 PraNew 、 Parallel Scavenge 回收老年代的收集器包括 Serial Old 、 Parallel Old 、 CMS 还有用于回收整个 Java 堆的 G1 收集器。不同收集器之间的连线表示它们可以搭配使用。 Serial 收集器复制算法 ): 新生代单线程收集器标记和清理都是单线程优点是简单高效 ParNew 收集器 ( 复制算法 ): 新生代收并行集器实际上是 Serial 收集器的多线程版本在多核 CPU 环境下有着比 Serial 更好的表现 Parallel Scavenge 收集器 ( 复制算法 ): 新生代并行收集器追求高吞吐量高效利用 CPU 。吞 吐量 用户线程时间 /( 用户线程时间 GC 线程时间 ) 高吞吐量可以高效率的利用 CPU 时间尽 快完成程序的运算任务适合后台应用等对交互相应要求不高的场景 Serial Old 收集器 ( 标记 - 整理算法 ): 老年代单线程收集器 Serial 收集器的老年代版本 Parallel Old 收集器 ( 标记 - 整理算法 ) 老年代并行收集器吞吐量优先 Parallel Scavenge 收 集器的老年代版本 CMS(Concurrent Mark Sweep) 收集器标记 - 清除算法 老年代并行收集器以获取最短回 收停顿时间为目标的收集器具有高并发、低停顿的特点追求最短 GC 回收停顿时间。 G1(Garbage First) 收集器 ( 标记 - 整理算法 ) Java 堆并行收集器 G1 收集器是 JDK1.7 提供的一 个新收集器 G1 收集器基于 “ 标记 - 整理 ” 算法实现也就是说不会产生内存碎片。此外 G1 收 集器不同于之前的收集器的一个重要特点是 G1 回收的范围是整个 Java 堆 ( 包括新生代老年 代 ) 而前六种收集器回收的范围仅限于新生代或老年代。 ZGC Z Garbage Collector 是一款由 Oracle 公司研发的以低延迟为首要目标的一款垃圾收 集器。它是基于动态 Region 内存布局暂时不设年龄分代使用了读屏障、染色指针和内 存多重映射等技术来实现可并发的标记 - 整理算法的收集器。在 JDK 11 新加入还在实验阶 段主要特点是回收 TB 级内存最大 4T 停顿时间不超过 10ms 。 优点 低停顿高吞吐 量 ZGC 收集过程中额外耗费的内存小。 缺点 浮动垃圾 目前使用的非常少真正普及还是需要写时间的。 新生代收集器 Serial 、 ParNew 、 Parallel Scavenge 老年代收集器 CMS 、 Serial Old 、 Parallel Old 整堆收集器 G1 ZGC 。 如何选择垃圾收集器 1. 如果你的堆大小不是很大比如 100MB 选择串行收集器一般是效率最高的。 参数 - XX:UseSerialGC 。 2. 如果你的应用运行在单核的机器上或者你的虚拟机核数只有单核选择串行收集器依然是合 适的这时候启用一些并行收集器没有任何收益。 参数 - XX:UseSerialGC 。 3. 如果你的应用是 “ 吞吐量 ” 优先的并且对较长时间的停顿没有什么特别的要求。选择并行收集 器是比较好的。 参数 - XX:UseParallelGC 。 4. 如果你的应用对响应时间要求较高想要较少的停顿。甚至 1 秒的停顿都会引起大量的请求失 败那么选择 G1 、 ZGC 、 CMS 都是合理的。虽然这些收集器的 GC 停顿通常都比较短但它 需要一些额外的资源去处理这些工作通常吞吐量会低一些。 参数 - XX:UseConcMarkSweepGC 、 - XX:UseG1GC 、 - XX:UseZGC 等。 从上面这些出发点来看我们平常的 Web 服务器都是对响应性要求非常高的。选择性其实就集 中在 CMS 、 G1 、 ZGC 上。而对于某些定时任务使用并行收集器是一个比较好的选择。 notify() 和 notifyAll() 有什么区别 notify 可能会导致死锁而 notifyAll 则不会 任何时候只有一个线程可以获得锁也就是说只有一个线程可以运行 synchronized 中的代码 使用 notifyall, 可以唤醒 所有处于 wait 状态的线程使其重新进入锁的争夺队列中而 notify 只能唤 醒一个。 wait() 应配合 while 循环使用不应使用 if 务必在 wait() 调用前后都检查条件如果不满足必须调 用 notify() 唤醒另外的线程来处理自己继续 wait() 直至条件满足再往下执行。 notify() 是对 notifyAll() 的一个优化但它有很精确的应用场景并且要求正确使用。不然可能导致 死锁。正确的场景应该是 WaitSet 中等待的是相同的条件唤醒任一个都能正确处理接下来的事 项如果唤醒的线程无法正确处理务必确保继续 notify() 下一个线程并且自身需要重新回到 WaitSet 中。