hutool使用 WeakReference

Full GC 、Major GC和 Minor GC有什么不同

 我们见过很多 GC 名词如:Minor GC、Young GC、Full GC、Old GC、Major GC、Mixed GC等。那么这么多GC如何进行大致区分?下面我们引用 R 大在知乎上的回答:

 针对 HotSpot VM 的实现,它里面的 GC 其实准确分类有两种:

Partial GC(局部 GC): 并不收集整个 GC 堆的模式

  • Young GC: 只收集 Young Gen 的 GC,Young GC 还有种说法就叫做 Minor GC,两者是一个意思;
  • Old GC: 只收集 old gen 的 GC,只有垃圾收集器 CMS 的 concurrent collection 是这个模式;
  • Mixed GC: 收集整个 Young Gen 以及部分 old gen 的 GC,只有垃圾收集器 G1 有这个模式;

Full GC(全局 GC): 收集整个堆,包括新生代,老年代,永久代(在 JDK 1.8 及以后,永久代被移除,换为 metaspace 元空间)等所有部分的模式;
接下来让我们再来了解下各个 GC:

(1)Minor GC / Young GC

首先我们先来看下 Minor GC / Young GC,大家都知道,新生代(Young Gen)也可以称之为年轻代,这两个名词是等价的。那么在年轻代中的 Eden 内存区域被占满之后,实际上就需要触发年轻代的 GC,或者是新生代的 GC。

其实就是所谓的 Minor GC,也可以称之为 Young GC。

(2)Old GC

所谓的老年代 GC,称之为 Old GC 更加合适一些,因为从字面意义上就可以理解,这就是所谓的老年代 GC。

(3)Full GC

对于 Full GC,可以说 Full GC 指的是针对新生代、老年代、永久代的全体内存空间的垃圾回收,所以称之为 Full GC。

(4)Major GC

上面我们提到,Major GC用于处理方法区的对象。这个区域不是用于存储那些从老年代存活下来的对象,这个区域也可能发生GC,发生概率很低。

(5)Mixed GC

Mixed GC 是 G1 中特有的概念,其实说白了,主要就是说在 G1 中,一旦老年代占据堆内存的 45%(-XX:InitiatingHeapOccupancyPercent:设置触发标记周期的 Java 堆占用率阈值,默认值是 45%。这里的Java 堆占比指的是 non_young_capacity_bytes,包括 old + humongous),就要触发 Mixed GC,此时对年轻代和老年代都会进行回收。Mixed GC 只有 G1 中才会出现。

WeakReference回收问题

 这个类算是一种标记,和C的指针给人的感有点像,但是起的作用可能比指针要大。我们都知道,java虚拟机的垃圾回收算法为可达性分析算法,即在回收垃圾前对垃圾进行分析和标记,然后这个标记的过程就是关键。

 WeakReference是在下一次gc的时候会将WeakReference所指向的内容回收,然后SoftReference则是在full gc的时候才会将指向的内容回收,那么问题就来了。reference真的这么蠢吗?也就是如果不仅仅只有reference引用了对应的实例,在可达性分析算法的root节点依然有对于这个实例的引用,这种情况下,reference通过get的结果会是空吗?

 怎么可能会是空呢?我们理一下逻辑就可以知道,其实所谓reference的作用其实就仅仅是在回收的时候提供一个标记,即如果在一般gc的情况下,发现某个实例有被softreference引用,那可达性分析就会判定这个对象不应该被回收,即其起到的作用大概可以被归纳为两点:

  • SoftReference可以拯救在gc中本应该被回收的实例
  • WeakReference可以确保一些实例在不需要的时候,及时地被抛弃
class TestReferecnce {
    @Test
    @Throws(Exception::class)
    fun testSomething() {
        var urlPatternTest:UrlPatternTest? = UrlPatternTest()
        val reference = WeakReference(urlPatternTest)
        reference.get().doIfNotNull { println("target exist") }
        println("execute gc")
        System.gc()
        reference.get().doIfNotNull { println("target exist") }
        reference.get().doIfNull { println("target not exist") }

        println("\n\nexecute gc after set null")
        urlPatternTest = null
        System.gc()
        reference.get().doIfNotNull { println("target exist") }
        reference.get().doIfNull { println("target not exist") }
    }
}
target exist
execute gc
target exist


execute gc after set null
target not exist

Process finished with exit code 

可以根据需求对每个模块单独引入,也可以通过引入hutool-all方式引入所有模块。

      <dependency>
        <groupId>cn.hutool</groupId>
        <artifactId>hutool-all</artifactId>
        <version>4.6.3</version>
    </dependency>

hutool使用文档

https://hutool.cn/docs/#/

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值