new Object()反映到 Java 堆中 , 形成一块存储了 Object 类型所有对象实例数据值的内存 。Java堆中还包含对象类型数据的地址信息 , 这些类型数据存储在方法区中 。
如何判断对象是否“死去”?
- 引用计数法
- 根搜索算法
引用计数法的缺点?很难解决对象之间的循环引用问题 。
什么是根搜索算法?通过一系列的名为“GC Roots”的对象作为起始点 , 从这些节点开始向下搜索,搜索所走过的路径称为引用链(Reference Chain),当一个对象到 GC Roots 没有任何引用链相连(用图论的话来说就是从 GC Roots 到这个对象不可达)时,则证明此对象是不可用的 。
文章插图
Java 的4种引用方式?在 JDK 1.2 之后,Java 对引用的概念进行了扩充,将引用分为
- 强引用 Strong Reference
- 软引用 Soft Reference
- 弱引用 Weak Reference
- 虚引用 Phantom Reference
软引用用来描述一些还有用,但并非必须的对象 。软引用所关联的对象,有在系统将要发生内存溢出异常之前,将会把这些对象列进回收范围,并进行第二次回收 。如果这次回收还是没有足够的内存,才会抛出内存异常 。提供了 SoftReference 类实现软引用 。
弱引用描述非必须的对象,强度比软引用更弱一些,被弱引用关联的对象,只能生存到下一次垃圾收集发生前 。当垃圾收集器工作时,无论当前内存是否足够,都会回收掉只被弱引用关联的对象 。提供了 WeakReference 类来实现弱引用 。
虚引用一个对象是否有虚引用,完全不会对其生存时间够成影响,也无法通过虚引用来取得一个对象实例 。为一个对象关联虚引用的唯一目的,就是希望在这个对象被收集器回收时,收到一个系统通知 。提供了 PhantomReference 类来实现虚引用 。
有哪些垃圾收集算法?
- 标记-清除算法
- 复制算法
- 标记-整理算法
- 分代收集算法
有什么缺点?效率问题:标记和清除过程的效率都不高 。
空间问题:标记清除之后会产生大量不连续的内存碎片,空间碎片太多可能导致,程序分配较大对象时无法找到足够的连续内存,不得不提前出发另一次垃圾收集动作 。
文章插图
复制算法(Copying)- 新生代将可用内存按容量划分为大小相等的两块,每次只使用其中一块 。当这一块的内存用完了,就将存活着的对象复制到另一块上面,然后再把已经使用过的内存空间一次清理掉 。
优点复制算法使得每次都是针对其中的一块进行内存回收,内存分配时也不用考虑内存碎片等复杂情况,只要移动堆顶指针,按顺序分配内存即可,实现简单 , 运行高效 。
缺点将内存缩小为原来的一半 。在对象存活率较高时,需要执行较多的复制操作,效率会变低 。
文章插图
应用商业的虚拟机都采用复制算法来回收新生代 。因为新生代中的对象容易死亡,所以并不需要按照1:1的比例划分内存空间,而是将内存分为一块较大的 Eden 空间和两块较小的 Survivor 空间 。每次使用 Eden 和其中的一块 Survivor 。
当回收时,将 Eden 和 Survivor 中还存活的对象一次性拷贝到另外一块 Survivor 空间上,最后清理掉 Eden 和刚才用过的 Survivor 空间 。Hotspot 虚拟机默认 Eden 和 Survivor 的大小比例是8:1,也就是每次新生代中可用内存空间为整个新生代容量的90%(80% + 10%),只有10%的内存是会被“浪费”的 。
标记-整理算法(Mark-Compact)-老年代标记过程仍然与“标记-清除”算法一样,但不是直接对可回收对象进行清理,而是让所有存活的对象向一端移动,然后直接清理掉边界以外的内存 。
文章插图
推荐阅读
- JVM学习笔记——类加载和字节码技术篇
- 详解pyautogui模块
- 2022-11-4 VideoPipe可视化视频结构化框架新增功能详解
- 详细了解JVM运行时内存
- 【JVM】关于JVM,你需要掌握这些 | 一文彻底吃透JVM系列
- Istio Ambient Mesh七层服务治理图文详解
- JVM学习笔记——垃圾回收篇
- 详解AQS中的condition源码原理
- JVM学习笔记——内存结构篇
- FHQ Treap 详解