Java内存泄漏引起的原因

近期各个行业正在复苏,本人也准备在IT行业从事一份工作。所需面试,发现一道面试题目有些不太明确,通过追查根底发现了一些有趣的事情。

题目如下:
Java中内存泄漏产生的原因可能有哪些?
首先看见这个问题,脑海里想起了堆,栈,方法区?
仔细琢磨了下,感觉不能这样回答,本人认为这个问题的深层次回答首先得从java有那些储存区域,什么是内存泄漏来回答。

  1. 寄存器(register)。这是最快的存储区,因为它位于不同于其他存储区的地方——处理器内部。

  2. 堆栈(stack)。创建程序时候,JAVA编译器必须知道存储在堆栈内所有数据的确切大小和生命周期,这一约束限制了程序的灵活性,所以虽然某些JAVA数据存储在堆栈中——特别是对象引用,但是JAVA对象不存储其中。

  3. 堆(heap)。编译器不需要知道要从堆里分配多少存储区域,也不必知道存储的数据在堆里存活多长时间。因此,在堆里分配存储有很大的灵活性。用堆进行存储分配比用堆栈进行存储存储需要更多的时间。

  4. 静态存储(static storage)。这里的“静态”是指“在固定的位置”。静态存储里存放程序运行时一直存在的数据。你可用关键字static来标识一个对象的特定元素是静态的,但JAVA对象本身从来不会存放在静态存储空间里。

  5. 常量存储(constant storage)。常量值通常直接存放在程序代码内部,这样做是安全的,因为它们永远不会被改变。有时,在嵌入式系统中,常量本身会和其他部分分割离开,所以在这种情况下,可以选择将其放在ROM中。

  6. 非RAM存储。若数据完全独立于一个程序之外,则程序不运行时仍可存在,并在程序的控制范围之外。
    技术文档:https://blog.csdn.net/qq_28009065/article/details/79087831

java六大储存区域已经知晓,那么还有一个问题什么是内存泄漏?
内存泄漏有个前提:GC。GC是垃圾收集的意思。是指JVM用于释放那些不再使用的对象所占用的内存。垃圾回收可以有效的防止内存泄露,有效的使用可以使用的内存。Java有了GC,就不需要程序员去人工释放内存空间。
对于程序员来说,GC基本是透明的,不可见的;但是根据Java语言规范定义,不保证JVM的垃圾收集器一定会执行。
什么是内存泄漏如此已经明确了,但是内存泄漏的根本原因是什么呢?长生命周期的对象持有短生命周期对象的引用就很可能发生内存泄漏,尽管短生命周期对象已经不再需要,但是因为长生命周期持有它的引用而导致不能被回收,这就是Java中内存泄漏的发生场景。
通过上网搜集,得到了内存泄漏产生的原因有以下六点:

  1. 静态集合类引起内存泄漏;
  2. 当集合里面的对象属性被修改后,再调用remove()方法时不起作用;
  3. 监听器
  4. 各种连接
  5. 内部类和外部模块的引用
  6. 单例模式

经过总结发现以下几点可以避免内存泄漏:

  1. 尽量避免使用 static 成员变量
  2. 避免 override finalize()
  3. 资源未关闭造成的内存泄漏
  4. 将内部类改为静态内部类
  5. 保持对对象生命周期的敏感,特别注意单例、静态对象、全局性集合等的生命周期。
    技术文档:
    https://blog.csdn.net/u012516166/article/details/77014910

下次在回答此类问题时,可以借鉴以上几点,通过多方面,多层次的探索,可以更加全面的了解java的内存机制,此类问题没有标准答案,需要多方面的回答,至此,敬上!

内容大多数还不太明白,借鉴了他人的劳动成果,并不是为了盈利获赞,而是通过自己写一遍,在自己将来运用到的时候能给自己带来些新的启发与感受。如有冒犯,多多包涵。

你可能感兴趣的:(Java内存泄漏引起的原因)