前往小程序,Get更优阅读体验!
立即前往
首页
学习
活动
专区
工具
TVP
发布
社区首页 >专栏 >易犯的Java内存泄漏代码

易犯的Java内存泄漏代码

作者头像
用户1263954
发布2018-01-30 15:09:52
1.7K0
发布2018-01-30 15:09:52
举报
文章被收录于专栏:IT技术精选文摘

Java隐式地通过GC(守护线程)回收内存。 GC定期检查是否存在无法访问的对象,或者确切地说,没有指向该对象的引用。如果是这样,GC回收新可用的内存。

现在的问题是我们应该担心内存泄漏还是Java如何处理它?

注意定义:当对象不可达(未使用)时或没有活动的线程可以访问它时,此对象可被作为垃圾进行回收

因此,如果在应用程序中有未使用的引用,但此引用无意中被对象持有,则不符合垃圾回收的条件,这就是潜在的内存泄漏。

GC处理不可达的对象,但无法确定未使用的对象。未使用的对象取决于应用程序逻辑,因此程序员必须注意业务代码。

内存泄漏可能会以许多方式发生,我将看一些例子。

示例1:自动装箱

你能发现内存泄漏吗?

这里我犯了一个错误。而不是将基本数据类型用于求和,我采用了Long(包装类),这是内存泄漏的原因。由于自动装箱,sum = sum + l;在每次迭代中创建一个新对象,因此将创建1000个不必要的对象。请避免在基本数据类型和包装类之间进行混合使用。

尽可能地使用基本的数据类型。

示例2:使用缓存

在这里,由于内部map数据结构而发生内存泄漏。此类用于显示缓存中的员工值。一旦显示完,就不需要将这些元素存储在缓存中。

我们忘记清除缓存,所以尽管应用程序不再需要缓存中的对象,但是它不能被GC回收,因为map对它们有很强的引用。

因此,当您使用自己的缓存时,如果不再需要缓存中的项目,请不要忘记清除它们。或者,您可以通过WeakHashMap初始化缓存。 WeakHashMap的优点是,如果key未被任何其他对象引用,则该条目将符合GC标准。

关于WeakHashMap需要谨慎的使用,如果要重新使用存储在缓存中的值,可能是它的key不被任何其他对象引用,因此该条目将被GC回收并且该值奇迹般地消失了。

示例3:关闭连接

在上面的例子中,我们关闭了try块中的连接(Costly)资源,所以在异常的情况下,连接不会被关闭。所以它会创建一个内存泄漏,因为这个连接永远不会返回到池中。

请始终把任何关闭的东西放在finally块中。

示例4:使用CustomKey

在CustomKey中,我们忘记提供equals()和hashcode()实现,因此映射get()方法检查hashcode()和equals()时,不能再检索存储在map中的键和值。但是这个条目不能被GC回收,因为map引用了它,但应用程序无法访问它。绝对是内存泄漏。

所以当你做自定义key时,总是提供一个equals和hashcode()的实现。

示例5:可修改的CustomKey

虽然这里我们为自定义key提供了equals()和hashcode(),但是在将其存储到map中后,我们无意中使得它可变。如果它的属性被更改,则该条目将永远不会被应用程序找到,但是map保存一个引用,所以发生内存泄漏。

始终使您的自定义key不变。

示例6:内部数据结构

这里我们面临一个棘手的问题,当Stack第一次增长然后收缩。实际上是由于内部的实现。堆栈内部保存一个数组,但是从应用程序的角度来看,Stack的活动部分是指针指向的位置。

所以当Stack增长到1000时,内部的数组单元格填满了元素,但之后当我们弹出所有元素时,指针变为零,所以根据应用程序它是空的,但内部数组包含所有弹出的引用。

在Java中,我们将其称为过时引用。过时的引用是不能取消的引用的引用。 该引用不能被GC回收,因为数组包含这些元素,但是在弹出后不必要。

要修复它,我们需要在弹出操作发生时设置空值,以便这些对象能够被GC回收。

防止内存泄漏的安全措施:

本文参与 腾讯云自媒体同步曝光计划,分享自微信公众号。
原始发表:2017-08-21,如有侵权请联系 cloudcommunity@tencent.com 删除

本文分享自 IT技术精选文摘 微信公众号,前往查看

如有侵权,请联系 cloudcommunity@tencent.com 删除。

本文参与 腾讯云自媒体同步曝光计划  ,欢迎热爱写作的你一起参与!

评论
登录后参与评论
0 条评论
热度
最新
推荐阅读
领券
问题归档专栏文章快讯文章归档关键词归档开发者手册归档开发者手册 Section 归档