您的位置:

java内存泄露,java内存泄露和溢出

本文目录一览:

java内存泄漏怎么处理

一、Java内存回收机制

不论哪种语言的内存分配方式,都需要返回所分配内存的真实地址,也就是返回一个指针到内存块的首地址。Java中对象是采用new或者反射的方法创建的,这些对象的创建都是在堆(Heap)中分配的,所有对象的回收都是由Java虚拟机通过垃圾回收机制完成的。GC为了能够正确释放对象,会监控每个对象的运行状况,对他们的申请、引用、被引用、赋值等状况进行监控,Java会使用有向图的方法进行管理内存,实时监控对象是否可以达到,如果不可到达,则就将其回收,这样也可以消除引用循环的问题。在Java语言中,判断一个内存空间是否符合垃圾收集标准有两个:一个是给对象赋予了空值null,以下再没有调用过,另一个是给对象赋予了新值,这样重新分配了内存空间。

二、Java内存泄露引起原因

首先,什么是内存泄露看经常听人谈起内存泄露,但要问什么是内存泄露,没几个说得清楚。内存泄露是指无用对象(不再使用的对象)持续占有内存或无用对象的内存得不到及时释放,从而造成的内存空间的浪费称为内存泄露。内存泄露有时不严重且不易察觉,这样开发者就不知道存在内存泄露,但有时也会很严重,会提示你Out of memory。

那么,Java内存泄露根本原因是什么呢看长生命周期的对象持有短生命周期对象的引用就很可能发生内存泄露,尽管短生命周期对象已经不再需要,但是因为长生命周期对象持有它的引用而导致不能被回收,这就是java中内存泄露的发生场景。具体主要有如下几大类:

1、静态集合类引起内存泄露:

像HashMap、Vector等的使用最容易出现内存泄露,这些静态变量的生命周期和应用程序一致,他们所引用的所有的对象Object也不能被释放,因为他们也将一直被Vector等引用着。

例:

Static Vector v = new Vector(10);

for (int i = 1; i100; i++)

{

Object o = new Object();

v.add(o);

o = null;

}//

在这个例子中,循环申请Object 对象,并将所申请的对象放入一个Vector 中,如果仅仅释放引用本身(o=null),那么Vector 仍然引用该对象,所以这个对象对GC 来说是不可回收的。因此,如果对象加入到Vector 后,还必须从Vector 中删除,最简单的方法就是将Vector对象设置为null。

2、当集合里面的对象属性被修改后,再调用remove()方法时不起作用。

例:

public static void main(String[] args)

{

Set set = new HashSet();

Person p1 = new Person("唐僧","pwd1",25);

Person p2 = new Person("孙悟空","pwd2",26);

Person p3 = new Person("猪八戒","pwd3",27);

set.add(p1);

set.add(p2);

set.add(p3);

System.out.println("总共有:"+set.size()+" 个元素!"); //结果:总共有:3 个元素!

p3.setAge(2); //修改p3的年龄,此时p3元素对应的hashcode值发生改变

set.remove(p3); //此时remove不掉,造成内存泄漏

set.add(p3); //重新添加,居然添加成功

System.out.println("总共有:"+set.size()+" 个元素!"); //结果:总共有:4 个元素!

for (Person person : set)

{

System.out.println(person);

}

}

3、监听器

在java 编程中,我们都需要和监听器打交道,通常一个应用当中会用到很多监听器,我们会调用一个控件的诸如addXXXListener()等方法来增加监听器,但往往在释放对象的时候却没有记住去删除这些监听器,从而增加了内存泄漏的机会。

4、各种连接

比如数据库连接(dataSourse.getConnection()),网络连接(socket)和io连接,除非其显式的调用了其close()方法将其连接关闭,否则是不会自动被GC 回收的。对于Resultset 和Statement 对象可以不进行显式回收,但Connection 一定要显式回收,因为Connection 在任何时候都无法自动回收,而Connection一旦回收,Resultset 和Statement 对象就会立即为NULL。但是如果使用连接池,情况就不一样了,除了要显式地关闭连接,还必须显式地关闭Resultset Statement 对象(关闭其中一个,另外一个也会关闭),否则就会造成大量的Statement 对象无法释放,从而引起内存泄漏。这种情况下一般都会在try里面去的连接,在finally里面释放连接。

5、内部类和外部模块等的引用

内部类的引用是比较容易遗忘的一种,而且一旦没释放可能导致一系列的后继类对象没有释放。此外程序员还要小心外部模块不经意的引用,例如程序员A 负责A 模块,调用了B 模块的一个方法如:

public void registerMsg(Object b);

这种调用就要非常小心了,传入了一个对象,很可能模块B就保持了对该对象的引用,这时候就需要注意模块B 是否提供相应的操作去除引用。

6、单例模式

不正确使用单例模式是引起内存泄露的一个常见问题,单例对象在被初始化后将在JVM的整个生命周期中存在(以静态变量的方式),如果单例对象持有外部对象的引用,那么这个外部对象将不能被jvm正常回收,导致内存泄露,考虑下面的例子:

class A{

public A(){

B.getInstance().setA(this);

}

....

}

//B类采用单例模式

class B{

private A a;

private static B instance=new B();

public B(){}

public static B getInstance(){

return instance;

}

public void setA(A a){

this.a=a;

}

//getter...

}

显然B采用singleton模式,它持有一个A对象的引用,而这个A类的对象将不能被回收。想象下如果A是个比较复杂的对象或者集合类型会发生什么情况

java在什么情况下会出现内存泄露

内存泄露就是指一个不再被程序使用的对象或变量一直被占据在内存中。java中的内存泄露的情况:

1.长生命周期的对象持有短生命周期对象的引用就很可能发生内存泄露,例如,缓存系统,我们加载了一个对象放在缓存中(例如放在一个全局map对象中),然后一直不再使用它,这个对象一直被缓存引用,但却不再被使用。

2.集合类,而如果集合类是全局性的变量(比如类中的静态属性,全局性的map等即有静态引用或final一直指向它),那么没有相应的删除机制,很可能导致集合所占用的内存只增不减,因此提供这样的删除机制或者定期清除策略非常必要。

3.单例模式。不正确使用单例模式是引起内存泄露的一个常见问题,单例对象在被初始化后将在JVM的整个生命周期中存在(以静态变量的方式),如果单例对象持有外部对象的引用,那么这个外部对象将不能被jvm正常回收,导致内存泄露

java内存泄露有哪些

1、静态集合类引起内存泄露:

像HashMap、Vector等的使用最容易出现内存泄露,这些静态变量的生命周期和应用程序一致,他们所引用的所有的对象Object也不能被释放,因为他们也将一直被Vector等引用着。

例:

Static Vector v = new Vector(10);

for (int i = 1; i100; i++)

{

Object o = new Object();

v.add(o);

o = null;

}//

在这个例子中,循环申请Object 对象,并将所申请的对象放入一个Vector 中,如果仅仅释放引用本身(o=null),那么Vector 仍然引用该对象,所以这个对象对GC 来说是不可回收的。因此,如果对象加入到Vector 后,还必须从Vector 中删除,最简单的方法就是将Vector对象设置为null。

2、当集合里面的对象属性被修改后,再调用remove()方法时不起作用。

例:

public static void main(String[] args)

{

SetPerson set = new HashSetPerson();

Person p1 = new Person("唐僧","pwd1",25);

Person p2 = new Person("孙悟空","pwd2",26);

Person p3 = new Person("猪八戒","pwd3",27);

set.add(p1);

set.add(p2);

set.add(p3);

System.out.println("总共有:"+set.size()+" 个元素!"); //结果:总共有:3 个元素!

p3.setAge(2); //修改p3的年龄,此时p3元素对应的hashcode值发生改变

set.remove(p3); //此时remove不掉,造成内存泄漏

set.add(p3); //重新添加,居然添加成功

System.out.println("总共有:"+set.size()+" 个元素!"); //结果:总共有:4 个元素!

for (Person person : set)

{

System.out.println(person);

}

}

3、监听器

在java 编程中,我们都需要和监听器打交道,通常一个应用当中会用到很多监听器,我们会调用一个控件的诸如addXXXListener()等方法来增加监听器,但往往在释放对象的时候却没有记住去删除这些监听器,从而增加了内存泄漏的机会。

4、各种连接

比如数据库连接(dataSourse.getConnection()),网络连接(socket)和io连接,除非其显式的调用了其close()方法将其连接关闭,否则是不会自动被GC 回收的。对于Resultset 和Statement 对象可以不进行显式回收,但Connection 一定要显式回收,因为Connection 在任何时候都无法自动回收,而Connection一旦回收,Resultset 和Statement 对象就会立即为NULL。但是如果使用连接池,情况就不一样了,除了要显式地关闭连接,还必须显式地关闭Resultset Statement 对象(关闭其中一个,另外一个也会关闭),否则就会造成大量的Statement 对象无法释放,从而引起内存泄漏。这种情况下一般都会在try里面去的连接,在finally里面释放连接。

5、内部类和外部模块等的引用

内部类的引用是比较容易遗忘的一种,而且一旦没释放可能导致一系列的后继类对象没有释放。此外程序员还要小心外部模块不经意的引用,例如程序员A 负责A 模块,调用了B 模块的一个方法如:

public void registerMsg(Object b);

这种调用就要非常小心了,传入了一个对象,很可能模块B就保持了对该对象的引用,这时候就需要注意模块B 是否提供相应的操作去除引用。

6、单例模式

不正确使用单例模式是引起内存泄露的一个常见问题,单例对象在被初始化后将在JVM的整个生命周期中存在(以静态变量的方式),如果单例对象持有外部对象的引用,那么这个外部对象将不能被jvm正常回收,导致内存泄露,考虑下面的例子:

class A{

public A(){

B.getInstance().setA(this);

}

....

}

//B类采用单例模式

class B{

private A a;

private static B instance=new B();

public B(){}

public static B getInstance(){

return instance;

}

public void setA(A a){

this.a=a;

}

//getter...

}

显然B采用singleton模式,它持有一个A对象的引用,而这个A类的对象将不能被回收。想象下如果A是个比较复杂的对象或者集合类型会发生什么情况

java的内存泄露是错误还是异常

java中内存泄漏有两种情况。

一是在堆中的分配的内存,在没有将其释放掉的时候,就将所有能访问这块内存的方式都删掉;另一种情况则是在内存对象明明已经不需要的时候,还仍然保留着这块内存和它的访问方式(引用)。在Java中已经由于垃圾回收机制的引入,第一种情况得到了很好的解决。所以,Java中的内存泄漏,主要指的是第二种情况。

Java的内存泄漏会导致程序效率低下、占用大量不需要的内存等问题。这将导致整个机器性能变差,内存泄露不是错误也不是异常,但是严重的话也会引起抛出OutOfMemoryError,导致程序崩溃。

java内存泄露,java内存泄露和溢出

2022-11-27
java内存泄露,java内存泄露的例子

2023-01-09
java内存泄露的看法,java内存泄露的看法怎么写

2022-11-23
java内存泄露分析方案,内存泄露Java

2022-11-18
java内存泄露分析,Java 内存泄漏

2023-01-05
Java内存泄露

Java内存泄露是指程序在分配内存后,不能正确的释放已不再使用的内存空间,这样恶性循环后,可用的内存空间就越来越少,最终可能导致系统资源耗尽。一、什么是Java内存泄露Java内存泄露通常发生在对象创

2023-12-08
java程序内存泄露问题刍议(java内存泄露是什么引起的)

2022-11-12
ThreadLocal内存泄露

2023-05-17
c语言内存泄露例子,c++怎么避免内存泄露

2022-12-02
java进程内存泄漏排查,java 内存泄漏排查

2022-11-21
java堆外内存泄漏重启,java内存泄漏原因

2022-11-26
这会导致java中的内存泄漏吗(java内存泄漏的原因及解决

2022-11-12
内存泄漏js代码,内存泄露代码

本文目录一览: 1、怎么解决内存泄漏js 2、如何自己检查NodeJS的代码是否存在内存泄漏 3、js循环引用引起的内存泄漏示例 4、autojs死巡环内存爆炸 怎么解决内存泄漏js 意外的全局变量

2023-12-08
php内存泄漏的后果,内存泄漏的危害

2022-11-25
php闭包函数内存泄露,php内存泄漏

2022-11-28
php守护进程可能的内存泄漏,php内存泄漏排查

2023-01-07
c语言内存泄漏如何定位,c内存泄漏分析

2022-11-25
java内存溢出,java内存溢出的原因

2023-01-08
java修改堆内存,java设置堆内存

2022-12-01
java内存溢出,java内存溢出代码实现

2022-11-30