Java学习笔记:内存泄漏

背景

Java的内存管理由JVM完成,GC和并发、解释器是JVM主要的三个模块。不像C++需要自己来alloc内存和释放内存来完成对象生命周期管理,Java根据对象的引用情况在适当的时间由JVM决定开始GC或在程序中手动触发GC。内存泄漏发生在需要alloc内存,而内存中已经无可GC的内存的情况下。

常见内存泄漏场景

巨大的静态对象

例如在类型中定义了巨大的static对象。由于该对象的生命周期直接与class的生命周期相关而无法被JVM回收。
解决办法自然是避免使用大的静态对象。

String.intern的使用

先说一下intern的发展历史方便理清思路。

  • Java 6之前和它的一些早期版本,String pool是在perm内存空间里且不可变的。
  • Java 6u30开始变得可以在程序运行之初改变。
  • Java 7开始设置在heap中且可以在运行之初设置,当然有一个默认的size。
  • Java 8将这个默认的size变大了。
    可以看出,不管是在perm还是heap上,即使可设置,这个size在程序运行时都是fix的。都是有可能在运行时发生outOfMemoryError的。只不过JVM演化过程中将更多的配置能力赋予程序运行者。
    由此,我们不难看出,解决办法是使用可设置pool大小的JDK版本,对程序的业务逻辑有清晰的认识从而预设一个合理的初始值。无论哪个版本,String pool的实现都是一个Map,因此,只需按照需求对这个初识值做一个线性估计即可。

没有关闭资源对象

这种curser,stream对象会用到缓存从而占用内存。比较需要注意的是,并不是把对象设置成null就可以解决这个问题,而是需要把他们关闭。因为即使设置null,底层资源还是在被打开的状态,有些资源也不在Java层。因此必须先close然后在设成null。对于Java 8以后,可以用try-with-close block来自动关闭,这只是一个语法糖。

总结

造成内存泄漏的原因有很多,但总结起来无非就是预防和良好的编程风格,该关闭的及时关闭,不用的对象手动复位,注意自己往容器里扔的对象的大小。

©著作权归作者所有,转载或内容合作请联系作者
平台声明:文章内容(如有图片或视频亦包括在内)由作者上传并发布,文章内容仅代表作者本人观点,简书系信息发布平台,仅提供信息存储服务。

推荐阅读更多精彩内容

  • No.1 “院长,我不同意!”极具责任意识的副院长对院长今天做的事感到不满,“收留一个这样的陌生人,我们这里可不是...
    郁逸默阅读 483评论 0 0
  • 今天学到了什么 1.1css背景 1.2背景的简写 1.3背景的吸附 1.4背景大小 1.5文本颜色 1.6 1....
    全梦妍阅读 156评论 0 3
  • 1、什么是教学服务?你的理解是什么? (1)定义:教师用专业和责任赢取客户信任的课堂外服务。 (2)我的理解: 教...
    千与千寻x阅读 216评论 1 0
  • 长夜里的孤独 它在唤醒我与时间的对白 “滴答滴答” 这是被诅咒的声音 音乐开始奏响 那飘散的音符 落在阳台上 覆盖...
    牧鱼girl阅读 146评论 0 2