java内存泄露分析
来源:互联网 发布:英语口语录音软件 编辑:程序博客网 时间:2024/04/28 21:26
内存泄露
所谓内存泄露就是指一个不再被程序使用的对象或变量一直被占据在内存中。 java中有垃圾回收机制,它可以保证一对象不再被引用的时候,即对象编程了孤儿的时候,对象将自动被垃圾回收器从内存中清除掉。由于Java 使用有向图的方式进行垃圾回收管理,可以消除引用循环的问题,例如有两个对象,相互引用,只要它们和根进程不可达的,那么GC也是可以回收它们的,例如下面的代码可以看到这种情况的内存回收:
- public class GarbageTest {
- public static void main(String[] args) throws IOException {
- try {
- gcTest();
- } catch (IOException e) {
- e.printStackTrace();
- }
- System.out.println("has exited gcTest!");
- System.in.read();
- System.in.read();
- System.out.println("out begin gc!");
- for(int i=0;i<100;i++)
- {
- System.gc();
- System.in.read();
- System.in.read();
- }
- }
- private static void gcTest() throws IOException {
- System.in.read();
- System.in.read();
- Person p1 = new Person();
- System.in.read();
- System.in.read();
- Person p2 = new Person();
- p1.setMate(p2); //p1中包含p2的引用
- p2.setMate(p1); //p2中包含p1的引用
- System.out.println("before exit gctest!");
- System.in.read();
- System.in.read();
- System.gc();
- System.out.println("exit gctest!");
- }
- private static class Person
- {
- byte[] data = new byte[20000000];
- Person mate = null;
- public void setMate(Person other)
- {
- mate = other;
- }
- }
- }
当gcTest()方法运行完毕以后,p1和p2对象都变成了垃圾,他们都不会被根对象所找到。关于根对象请参见《JVM垃圾回收机制总结(2) :基本算法概述 》中的关于“垃圾回收从哪里开始”的讨论。
Java的内存泄露
虽然Java的垃圾回收机制较大程度的降低了内存泄露的可能性,但Java程序员仍然可能会写出发生内存泄露的代码。其原因就是一个已经不被使用的短寿命对象被一个长寿命对象(如类的静态成员对象)引用,这就使得本来要被回收的短寿命对象永远无法被回收,造成内存泄露。
内存泄露的典型情况
(1) 数据结构造成的短暂内存泄露问题,看下面的代码
- public class Stack{
- private Object[] element=new Object[10];
- private int size=0;
- public void push(Object ele){
- ensureCapacity();
- element[size++]=ele;
- }
- public Object pop(){
- if(size==0) throw new EmptyStackException();
- return element[--size]; //短暂造成内存泄露
- }
- private void ensureCapacity(){
- if(element.length==size){
- Object[] oldElement=element;
- element=new Object[size*2+1];
- System.arraycopy(oldElement,0,element,0,size);
- }
- }
- }
上面的代码每一次pop()的时候,Stack都会弹出一个元素,在没有加入新元素之前,实际上仍然有一个引用element[x]指向了这个已经弹出的对象,因此GC是不会对其进行垃圾回收的。只有push()新元素的时候使得element[x]=newObject,才会使得以前创建的对象有可能被回收。应该把上面的pop()方法改成下面的代码就安全多了:
- public Object pop(){
- if(element.length==size) throws EmptyStackException();
- Object o=element[--size];
- elements[size]=null; //使得GC有机会回收这个对象
- return o;
- }
0 0
- Java内存泄露分析
- java内存泄露分析
- JAVA分析内存泄露
- Java内存泄露问题分析
- Java内存泄露问题分析
- Java内存泄露问题分析
- Java内存泄露问题分析
- Java内存泄露问题分析
- Java内存泄露问题分析
- Java内存泄露和分析
- java内存泄露分析方案
- java 内存泄露分析(jmap + MemoryAnalyzer)
- JAVA内存泄露的原因分析
- Java内存泄露分析, WeakReference与SoftReference
- 【转】JAVA内存泄露分析及解决
- java 内存泄露分析工具-mat
- java中内存泄露有几种?如何分析泄露原因
- Java常见问题分析(内存溢出、内存泄露、线程阻塞等)
- 新版Ubuntu 13.0将集成OpenStack Havana
- 数据结构 二叉树的实现 c语言版
- (孙鑫 十八)ActiveX 控件
- 第三周作业——冒泡排序和归并排序
- 数位DP
- java内存泄露分析
- (孙鑫 十九)动态连接库
- C语言重新学习笔记一
- eclipse中编辑log4j 的xml配置文件时,自动提示
- TortoiseSVN 1.8 关于右键的设置
- 黑马程序员-IOS开发之--C语言基础-复杂数据类型等
- (孙鑫 二十) HOOK和数据库访问
- [shell] expect完整介绍
- (intermediate) 混合图欧拉回路 UVA 10735 - Euler Circuit