内存泄漏(Memory Leak)通常指的是计算机程序中一种资源管理失当的问题。简单来说,就是程序申请了内存空间,但在不再使用它的时候,没有将其释放,导致这部分内存一直被占用,且无法被程序再次访问或操作系统回收。

为什么会内存泄漏?

在Java中,当一个对象A拥有另一个对象B的引用时,如果B只有来自A的这一个引用,并且A一直没有释放,则B也不会被释放。因为JVM并不知晓代码的业务逻辑,他只知道B还被其他对象引用,并且A也正在使用之中。因此JVM会认为,B对象还不可以回收。

然而,A对象没有移除到B对象的这个引用,有可能是因为业务逻辑处理不当所致。例如,当A是一个单例的全局对象管理器,管理一系列对象,而B对象恰好在业务逻辑中应该被回收,而没有回收时,B会一直存在于A的引用中。此时B就无法进入正常的回收逻辑中了。

如何避免内存泄漏

  1. 在任何时刻,创建对象时,都要思考一下生命周期。 可以试着问问自己:目前的这个对象被创建后,它应该在什么时候被销毁?是这个函数结束时、副本玩法结束时、组队结束时、玩家下线时、还是一直到服务器停止后?
  2. 考虑不使用引用,而使用id等基础数据类型进行关联 这个对象创建之后,要离开创建它的函数,就一定要被其他对象管理。在管理器之外,还会被其他对象引用吗?如果是,那么要考虑其引用什么时候结束。或者,如果管理器能提供唯一的id进行管理,那么在其他对象上就存储一个唯一的id,在需要时再通过id向管理器查询出对象,在函数调用栈中使用,随着函数结束后栈帧弹出回收。
  3. 在外部补充业务逻辑,检查内存泄漏 如果业务足够复杂,系统陈旧,无法进行彻底排查泄露的位置,可以考虑每隔一段时间检查内存中是否有内存泄漏,然后强行将其清除。相当于是在业务层执行一次垃圾回收行为。
  4. 定义过期时间,限制使用条件 如果业务复杂,可以考虑在对象使用时加一个过期时间,超过时间还被访问,则执行清理。