强软弱虚引用以及threadlocal

又是一个被讲烂的东西,但是我还是总结一下,日后也可以自己看。

一、强引用

A a = new A(); a是强引用,new A();是对象。我们99%都是用这样形式,不多说,不举例。

二、软引用

软引用是说当内存不足时,也就是快oom之前,它会去把只有软引用引用的对象删除。例子如下:

结果如下:

三、弱引用

弱引用是说当第一次GC时候,删除只有弱引用引用的对象。例子如下:

结果如下:

四、虚引用(幽灵引用)

虚引用在任何时间都可能被删除,而且无论何时使用get方法都会返回null。他必须搭配RefrenceQueue使用,除了虚引用,软引用和弱引用都可以使用RefrenceQueue,而且用法都一样。这里就用虚引用做例子。例子如下:

结果如下:

五、threadlocal之oom

很多同行发博客我觉得已经失去了初心,我认为这是一个做技术人最纯粹的东西,但是现在很多人没有搞清楚或者复制别人的贴子,也许这也是大家认为谷歌比百度好的原因,但我不管环境怎么样,我的文章一定是原创,一定是我验证过的。

threadlocal里有个threadlocalmap,这个map自定义了一个entry,这个entry key是弱引用,value是threadlocal的值。

1、如果你用如下方式用threadlocal(我们大多数也是这么用的,阿里的java开发规范也是建议这么用的)

这里threadlocal是一个静态私有的成员变量,我们之前有说过弱引用只有当对象只有弱引用时候才会被GC清除,那么这样写就是有一个强引用,那么就不会出现很多文章说的出现key为null,value有值的entry。但是这样也会oom,比如线程太多,每个线程放到threadllocal里数据太大,也会oom。这里是oom第一个原因。

2、如果采用私有变量,那么会出现网上大部分文章说的key为null,从而导致oom的情况

原因解释:这里设置了threadlocal并且赋了值,但是他没有强引用。那么当第一次GC,时候entry里的key会被清空,value保留值。但是仅仅这样也是不会oom,还要有2个条件。

①就是所运行的线程不能结束,因为线程结束threadlocalmap也没了,自然不会oom。

②线程运行过程中不再执行set、get、remove命令

当线程运行过程中发生了GC,那么会留下一个空key的entry。并且没有执行set、get、remove,因为这3个命令都会清空key为null的entry。当满足这两个条件,请求线程再多一点,就会出现oom了。

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值