加入收藏 | 设为首页 | 会员中心 | 我要投稿 济源站长网 (https://www.0391zz.cn/)- 数据工具、数据仓库、行业智能、CDN、运营!
当前位置: 首页 > 站长资讯 > 动态 > 正文

Java中七个潜在的内存泄露风险

发布时间:2021-03-24 15:14:58 所属栏目:动态 来源:互联网
导读:文中的单元测试就可以顺利通过了,需要注意的是这个场景比较隐蔽,一定要在平时的代码中注意。 4. 非静态内部类 要知道,所有的非静态类别类都持有外部类的引用,因此某些情况如果引用内部类可能延长外部类的生命周期,甚至持续到进程结束都不能回收外部类的

文中的单元测试就可以顺利通过了,需要注意的是这个场景比较隐蔽,一定要在平时的代码中注意。

4. 非静态内部类

要知道,所有的非静态类别类都持有外部类的引用,因此某些情况如果引用内部类可能延长外部类的生命周期,甚至持续到进程结束都不能回收外部类的空间,这类内存溢出一般在Android程序中比较多,只要MyAsyncTask处于运行状态MainActivity的内存就释放不了,很多时候安卓开发者这样做只是为了在内部类中拿到外部类的属性,殊不知,此时内存已经泄露了。

M对重写了finalize()的类的处理稍微不同,首先会针对这个类创建一个java.lang.ref.Finalizer类,并让java.lang.ref.Finalizer持有这个类的引用,在上文中的例子中,因为Finalizer类的引用被java.lang.ref.Finalizer持有,所以他的实例并不能被Young GC清理,反而会转入到老年代。在老年代中,JVM GC的时候会发现Finalizer类只被java.lang.ref.Finalizer引用,因此将其标记为可GC状态,并放入到java.lang.ref.Finalizer.ReferenceQueue这个队列中。等到所有的Finalizer类都加到队列之后,JVM会起一个后台线程去清理java.lang.ref.Finalizer.ReferenceQueue中的对象,之后这个后台线程就专门负责清理java.lang.ref.Finalizer.ReferenceQueue中的对象了。这个设计看起来是没什么问题的,但其实有个坑,那就是负责清理java.lang.ref.Finalizer.ReferenceQueue的后台线程优先级是比较低的,并且系统没有提供可以调节这个线程优先级的接口或者配置。因此当我们在使用使用重写finalize()方法的对象时,千万不要瞬间产生大量的对象,要时刻谨记,JVM对此类对象的处理有特殊逻辑。

6. 针对长字符串调用String.intern()

如果提前在src/test/resources/large.txt中写入大量字符串,并且在Java 1.6及以下的版本运行下面程序,也将得到一个OOM

(编辑:济源站长网)

【声明】本站内容均来自网络,其相关言论仅代表作者个人观点,不代表本站立场。若无意侵犯到您的权利,请及时与联系站长删除相关内容!

    热点阅读