一、本文参考:
1.《深入理解java虚拟机 JVM高级特性与最佳实践》
2.http://coderevisited.com/memory-leaks-in-java/
二、对象已死的判定方法
要进行JVM中对象回收首先要判断对象是否已经死亡,判断的方法有如下几个:
1.引用计数法
给对象中添加一个引用计数器,每当有一个地方引用它时,计数器值就加1;当引用失效时,计数器值就减1;任何时刻 计数器为0的对象就是不可能再被使用的。
但是主流的java虚拟机里面没有选用引用计数器算法来管理内存,其中最主要的原因是它很难解决对象之间相互循环引用的问题。
2.可达性分析算法
这个算法的基本思想就是通过一系列的称为“GC Roots"的对象作为起始点,从这些节点开始向下搜索,搜索所走过的路径称为引用链,当一个对象到GC Roots没有任何引用链相连接时,则证明此对象是不可用的。如下图所示,对象object5、object6、object7虽然互相有关联,但是它们到GC Roots是不可达的,所以它们将会被判定为是可回收对象。
三、导致内存泄漏的情况及代码
java 堆内存泄漏。是由于java对象不停创建但是没有释放对象引用导致的。
以下是关于java代码,此代码是引自http://coderevisited.com/memory-leaks-in-java/
类com.code.revisited.memoryleaks.Stack提供了实现栈的一些方法,包括遍历,入栈,出栈等操作。假设原来目的是为了现实使用(当然这里是为了解释内存泄漏)。
package com.code.revisited.memoryleaks;import java.util.Iterator;
import java.util.NoSuchElementException;/*** @author sureshsajja* */
public class Stack<E> implements Iterable<E> {private int N;private E[] array;@SuppressWarnings("unchecked")public Stack(int capacity) {array = (E[]) new Object[capacity];}@Overridepublic Iterator<E> iterator() {return new StackIterator();}private class StackIterator implements Iterator<E> {private int i = N - 1;@Overridepublic boolean hasNext() {return i >= 0;}@Overridepublic E next() {if (!hasNext()) {throw new NoSuchElementException();}return array[i--];}@Overridepublic void remove() {throw new UnsupportedOperationException();}}public void push(E item) {if (isFull()) {throw new RuntimeException("Stack overflow");}array[N++] = item;}public E pop() {if (isEmpty())throw new RuntimeException("Stack underflow");E item = array[--N];return item;}public boolean isEmpty() {return N == 0;}public int size() {return N;}public boolean isFull() {return N == array.length;}public E peek() {if (isEmpty())throw new RuntimeException("Stack underflow");return array[N - 1];}}

类com.code.revisited.memoryleaks.StackTest用于执行栈操作。要进行入栈及出栈10000次操作,理想是入栈时分配堆内存,出栈后对象被回收。

package com.code.revisited.memoryleaks;/*** @author  sureshsajja**/
public class StackTest {/*** @param args*/public static void main(String[] args) {Stack<Integer> s = new Stack<Integer>(10000);for (int i = 0; i < 10000; i++) {s.push(i);}while (!s.isEmpty()) {s.pop();}while (true ) {// do something
              }}}

执行开始。我们使用VisualVM进行观察。为了更明显一些,将栈操作部分代码注释也执行一下。
package com.code.revisited.memoryleaks;/*** @author  sureshsajja**/
public class StackTest {/*** @param args*/public static void main(String[] args) {
//            Stack<Integer> s = new Stack<Integer>(10000);
//            for ( int i = 0; i < 10000; i++) {
//                   s.push(i);
//            }
//
//            while (!s.isEmpty()) {
//                   s.pop();
//            }while (true ) {// do something
              }}}

把栈操作的设为1号,没有栈操作的设置为2号,分别生成Heap Dump文件,我们看一下类实例的截图:

首先是1号截图
首先是2号截图

显然预期的栈操作出栈后并没有释放掉Integer对象的引用(实际上看代码也知道),所以不会被GC回收。真正的实际情况这种引用将会很隐蔽,但是根本总是由于对象仍然被引用。
四、结语
本篇仅对java堆内存泄漏进行了简单说明,下一篇将讨论其他相关的内存泄漏。有不对的地方欢迎拍砖>_<

转载于:https://www.cnblogs.com/bobsha/p/5228335.html

为什么JAVA的垃圾回收机制无法避免内存泄漏相关推荐

  1. js垃圾回收机制和引起内存泄漏的操作

    Js具有自动垃圾回收机制.垃圾收集器会按照固定的时间间隔周期性的执行. JS中最常见的垃圾回收方式是标记清除. 工作原理:是当变量进入环境时,将这个变量标记为"进入环境".当变量离 ...

  2. 面试题——js垃圾回收机制和引起内存泄漏的操作

    JS的垃圾回收机制了解吗? Js具有自动垃圾回收机制.垃圾收集器会按照固定的时间间隔周期性的执行. JS中最常见的垃圾回收方式是标记清除. 工作原理:是当变量进入环境时,将这个变量标记为"进 ...

  3. java的垃圾回收机制包括:主流回收算法和收集器(jvm的一个主要优化方向)

    2019独角兽企业重金招聘Python工程师标准>>> java的垃圾回收机制是java语言的一大特色,解放了开发人员对内存的复杂控制,但如果你想要一个高级java开发人员,还是需要 ...

  4. JAVA虚拟机垃圾回收机制和JAVA排错三剑客

    一.Java虚拟机逻辑回收机制 1.Java垃圾回收器 Java垃圾回收器是Java虚拟机(JVM)的三个重要模块(另外两个是解释器和多线程机制)之一,为应用程序提供内存的自动分配(Memory Al ...

  5. 【Java】Java的垃圾回收机制小结

    文章目录 1. Java的垃圾回收机制? 1.1 Java的引用类型 1.2 哪些内存需要回收? 1.3 怎么定义垃圾? 1.4 怎么回收垃圾? 2. JVM一次完整的GC流程? 3.触发GC之后,会 ...

  6. [Java基础] 垃圾回收机制

    ​写在前面 本文简单介绍一下Java的垃圾回收机制相关概念. ​ 活动地址:CSDN21天学习挑战赛 学习的最大理由是想摆脱平庸,早一天就多一份人生的精彩:迟一天就多一天平庸的困扰.各位小伙伴,如果您 ...

  7. Java的垃圾回收机制介绍

    1.java的语言框架 (1)CPU->操作系统内核->应用层框架->JVM(java虚拟机)->Java字节码->Java源代码 (2)java是解释型语言,嵌入式常用 ...

  8. java垃圾回收机制_乐字节Java|GC垃圾回收机制、package和import语句

    本文接上一篇:乐字节Java|this关键字.static关键字.block块.本文是接着讲述JavaGC垃圾回收机制.package 和 import语句. 一.GC垃圾回收机制 GC全名:Garb ...

  9. 不要再问我“Java GC垃圾回收机制”了

    点击蓝色"程序猿DD"关注我 回复"资源"获取独家整理的学习资料! Java GC垃圾回收几乎是面试必问的JVM问题之一,本篇文章带领大家了解Java GC的底 ...

最新文章

  1. SVG.js 笔记 (一)
  2. 孔雀翎----《Programming C# 》中文版 第4版
  3. 证明并推导汉诺塔(河内之塔)问题公式
  4. mysql的基本的查询语句_Mysql的基本查询语句
  5. UML 中关系详解以及在visio中的表示
  6. DNS视图及日志系统
  7. ps流 转发_RTP协议全解析(H264码流和PS流)(转)
  8. android 定位 广播,android - 如何触发广播接收器在GPS开启/关闭? - SO中文参考 - www.soinside.com...
  9. hibernate示例_通过示例Hibernate–第1部分(删除孤儿)
  10. HUE Load Balancer 启动失败
  11. Redis Sentinel 模拟故障迁移
  12. mysql导入表error 1067_mysql 导入数据error 1067(42000) Invalid default value for 'update'
  13. 文件没有后缀名,如何批量添加为.jpg
  14. shell脚本一键安装jdk
  15. html做一个年份月份天数选择器,jquery编写日期选择器
  16. PPT计算机辅助教学,计算机辅助教学与多媒体课件制作
  17. 基于WeX5平台开发微信公众号中的在线问卷调查
  18. 修改ffmpeg支持文件描述符,以适配android10沙箱机制
  19. python开发小程序拼团_拼团商城模式开发(如何开发)
  20. Zuul网关服务使用详解

热门文章

  1. Virtural Box 虚拟ubuntu 修改分辨率
  2. 系统带你学习 WebAPIs 第三讲
  3. ES5-7 立即执行函数、闭包深入、逗号运算符
  4. Java学习笔记之equals和Objects.equals
  5. Linux基础入门学习笔记之二
  6. ios PNG Crush error (PNG图片错误)
  7. 学一下Unix/C啊
  8. 金属圆柱求取倾斜角度
  9. 【图像处理面试题】——1
  10. 【图像处理】——opencv常用函数