A股上市公司传智教育(股票代码 003032)旗下技术交流社区北京昌平校区

 找回密码
 加入黑马

QQ登录

只需一步,快速开始

大家知道,Java 中内存泄漏就是存在一些被分配的对象,这些对象有下面两个特点,
首先,这些对象是可达的,即在有向图中,存在通路可以与其相连;
其次,这些对象是无用的,即程序以后不会再使用这些对象。
如果对象满足这两个条件,这些对象就可以判定为Java 中的内存泄漏,这些对象不会被GC 所回收,
然而它却占用内存。
在C++中,内存泄漏的范围更大一些。有些对象被分配了内存空间,然后却不可达,
由于C++中没有GC,这些内存将永远不回来。在Java 中,这些不可达的对象都由GC 负责回收,因此程序员不需要考虑这部分的内存泄漏。通过分析,可以得知,对于C++,程序员需要自己管理边和顶点,而对于Java 程序员只需要管理边就可以了(不需要管理顶点的释放)。通过这种方式,Java 提高了编程的效率。

我举出一种内存泄漏的例子说明一下,代码如下:
Vector v = new Vector(10);

for (int i = 1; i<100; i++)

{Object o = new Object();

v.add(o);

o = null;

}//

细心的人会发现,在这个例子中,循环申请Object 对象,并将所申请的对象放入一个Vector 中,如果仅仅释放引用本身,那么Vector 仍然引用该对象,所以这个对象对GC 来说是不可回收的。

现在我就是想知道 上面这个例子中这种情况该如何避免呢? 还有就是避免和发现内存泄漏方法有哪些?求高手指教

评分

参与人数 1技术分 +1 收起 理由
黄玉昆 + 1 赞一个!

查看全部评分

3 个回复

倒序浏览
简单修改了一下你的代码:
  1. Vector v = new Vector(10);
  2.                 Object o = new Object();
  3.                 for (int i = 1; i < 100; i++){
  4.                         v.add(o);
  5.                         o = null;

  6.                 }
复制代码
避免内存泄漏的方法:
1.为了更快的让垃圾回收机制回收那些不在使用的对象,可以通过将该对象的引用变量设置为null,通过这种方式暗示垃圾回收机制可以回收该对象。
2.可以调用对象的finalize()方法或System.gc()等方法来建议系统进行垃圾回收,但这种方法仅仅是建议,依然不能精确控制垃圾回收机制的执行。
希望对你有说帮助。
回复 使用道具 举报
java  与 c++ 不同的 java程序只能jvm平台上运行,就必要深入了解sun公司Hotspot 的 JVM 底层到底如何工作?
java经过编译生成class 一系列二进制流数据文件,经过jre解释器装载,字节码校验,符号引用动态链接,初始化,分配堆栈,堆,方法区,本地方法区,寄存器 各区内存

在java常出现的内存泄露与内存溢出,体现各内存区边界溢出
1.常量池内存溢出
2.方法区永久代溢出,class Loader ,字节码框架常出现
3.栈线程溢出,体现两方面 一方面是 栈帧内存块溢出 另外一方面是线程数量过多
4.堆区溢出,分新生代,老年代,而新生代又有两个区,Eden 区,Survivor区
5.本地方法区 ,与操作系统本地c语言函数库与c++类库有关

解决内存溢出
1.在程序上进一步 优化,覆写object的final()进一步堆区老年代不必要的对象手动清理,或是手动启动垃圾收集器gc线程
2.jvm 内存参数配置,此配置 大小决定了jvm 的monior gc的频率,垃圾收集器有好几种,常见算法 搜索树,标记-清理,分代收集,注意java当中并没有用 引用计数器算法,循环引用 很难解决
3.java自带的 Jconsole 与 Jvisualvm,可视图工具分析
4.jhat 与 jmap 命令,对堆转储dump文件分析






评分

参与人数 1技术分 +1 收起 理由
黄玉昆 + 1 很给力!

查看全部评分

回复 使用道具 举报
您需要登录后才可以回帖 登录 | 加入黑马