精华内容
下载资源
问答
  • 通过一个Demo来简要介绍下ThreadLocal和ClassLoader导致内存泄露最终OutOfMemory的场景。下面通过示例代码给大家分享Java内存泄露的相关知识,感兴趣的朋友一起看看吧
  • NULL 博文链接:https://cyj86.iteye.com/blog/1095213
  • java存在内存泄漏吗?

    2020-11-30 18:17:37
    即使这样,Java中也存在着内存泄漏得情况: 一:当长生命周期得对象持有短生命周期得对象引用,就很可能发生内存泄漏。尽管短生命周期得对象已经不再需要,但是长生命周期得对象一直持有他的引用导致其无法被回收。...

    内存泄漏:是指对象或者变量没有被引用,却一直占据在内存中,使得这一块内存不能够再被利用起来,造成内存的不可被用称为泄漏。

    但是Java中有垃圾回收机制GC,GC能够将不再被使用的对象,自动从内存中清除。
    即使这样,Java中也存在着内存泄漏的情况:

    一:当长生命周期的对象持有短生命周期的对象引用,就很可能发生内存泄漏。尽管短生命周期的对象已经不再需要,但是长生命周期的对象一直持有他的引用导致其无法被回收。例如,缓存系统;加载一个对象放在缓存系统中,一直不去使用这个对象,但是它一直被缓存引用,所以不会被回收导致缓存泄漏。

    检查java中的内存泄漏,一定要将程序各个分支情况都完成执行至结束,然后看其是否被使用过,如果没有才能判定这个对象属于内存泄漏。

    二:当一个对象被存储进HashSet集合中,就不可修改这个对象中用于计算哈希值的属性了。否则,对象修改后的哈希值与刚添加进HashSet集合时的哈希值不一样,此时如果将当前对象的引用作为参数,用contaions方法判断对象是否存在,则会返回找不到对象的结果。这会导致无法从HashSet单独删除当前对象,造成内存泄漏。

    展开全文
  • 解决Java加载dll导致Java进程内存泄露在做网络监控系统的性能测试时,出现了内存泄露的问题,困扰了很久,现在终于算是解决了,但是根本原因尚不明确,拿出来大家讨论下,看看能不能完美解决~ 这个问题奇怪的地方...

    解决Java加载dll导致Java进程内存泄露在做网络监控系统的性能测试时,出现了内存泄露的问题,困扰了很久,现在终于算是解决了,但是根本原因尚不明确,拿出来大家讨论下,看看能不能完美解决~  这个问题奇怪的地方在于是Java进程内存泄露,而不是平常的JVM内存泄露,用Jprofile等工具也无法看出问题所在。  测试代码如下:System.loadLibrary("test1");int threadPoolSize =

    解决Java加载dll导致Java进程内存泄露

    在做网络监控系统的性能测试时,出现了内存泄露的问题,困扰了很久,现在终于算是解决了,但是根本原因尚不明确,拿出来大家讨论下,看看能不能完美解决~

    这个问题奇怪的地方在于是Java进程内存泄露,而不是平常的JVM内存泄露,用Jprofile等工具也无法看出问题所在。

    测试代码如下:System.loadLibrary("test1");

    int threadPoolSize =

    400;

    ExecutorService service = Executors.newFixedThreadPool(threadPoolSize);

    for (int i =

    0; i <

    400; i++) {

    service.submit(new Runnable() {

    public

    void run() {

    while (true) {

    try {

    Thread t =

    new Thread();

    t.start();

    Thread.sleep(100);

    } catch (Exception e) {

    e.printStackTrace();

    }

    }

    }

    });

    }

    说明:此段代码所做的工作就是加载一个dll,然后不断的启动线程(线程什么也不做,直接终止)。

    注:线程池只是为了加速问题复现,无其他用处。

    现象:

    1.如果不加载dll,只不断的启动线程,Java进程内存正常,不会一直增长。

    2.如果加载附件中test1的

    msimg32.dll

    ,Java进程内存会一直增长。

    3.如果加载附件中test2的dll(需要安装C++运行环境vcredist_x86),Java进程内存正常,不会一直增长。

    DLL说明:

    dll的工程源码在附件中,test1和test2的区别只在于编译选项,如附件:test1选择的是“使用标准Windows库”或“在静态库中使用MFC”,test2选择的是“在共享DLL中使用MFC”

    此dll工程的特点在于使用了jni,并引入了mfc头文件【#include 】,如果不引入mfc头文件则不会引起内存泄漏

    目前此问题的根本原因尚不明确,怀疑是jdk的bug(使用最新的jdk1.6.0.23也没用),不知道大家有什么想法吗?欢迎大家讨论~

    基于广大用户反馈,论坛附件下载策略全新上线,下载券全站通用,请放心下载 。

    收藏0

    打赏0

    点赞0

    分享至:

    评论

    文明留言,专业沟通

    4d2a07ae94f6972507ccebf791e8f739.png

    请先 登录,再评论!

    全部评论

    相关推荐

    展开全文
  • 一、Java内存回收机制 不论哪种语言的内存分配方式,都需要返回所分配内存的真实地址,也就是返回一个指针到内存块的首地址。Java中对象是采用new或者反射的方法创建的,这些对象的创建都是在堆(Heap)中分配的,所有...

    一、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; i<100; 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是个比较复杂的对象或者集合类型会发生

    展开全文
  • 此问题在项目中被发现,经查看JDK源码(JDK1.6),String类的public String substring(int beginIndex, int endIndex)的...1importjava.util.ArrayList;2importjava.util.List;34publicclassLeakTest{5publicstaticvo...

    此问题在项目中被发现,经查看JDK源码(JDK1.6),String类的public String substring(int beginIndex, int endIndex)的实现让我很意外。

    想重现这个场景很容易,请看代码。

    1

    4f1150b881333f12a311ae9ef34da474.pngimportjava.util.ArrayList;24f1150b881333f12a311ae9ef34da474.pngimportjava.util.List;34f1150b881333f12a311ae9ef34da474.png41fa987a29c6482f53d401256f96355eb.png

    ca75c07623e1b494fee67e8f316fc310.gifpublicclassLeakTest9b8a8a44dd1c74ae49c20a7cd451974e.png{597e794c86028c5f5b5461ae5ef440a4c.png

    3c6cafce68eb941a00f1998f1d3d3aa6.gifpublicstaticvoidmain(String

    9b8a8a44dd1c74ae49c20a7cd451974e.pngargs)9b8a8a44dd1c74ae49c20a7cd451974e.png{6d18c02628675d0a2c816449d98bda930.png        Listhandler=newArrayList();797e794c86028c5f5b5461ae5ef440a4c.png

    3c6cafce68eb941a00f1998f1d3d3aa6.giffor(inti=0; i<100000; i++)9b8a8a44dd1c74ae49c20a7cd451974e.png{8d18c02628675d0a2c816449d98bda930.png            Huge h=newHuge();9d18c02628675d0a2c816449d98bda930.png            handler.add(h.getSubString(1,5));10ecedf933ec37d714bd4c2545da43add2.png        }11ecedf933ec37d714bd4c2545da43add2.png    }128f1ba5b45633e9678d1db480c16cae3f.png}134f1150b881333f12a311ae9ef34da474.png141fa987a29c6482f53d401256f96355eb.png

    ca75c07623e1b494fee67e8f316fc310.gifclassHuge9b8a8a44dd1c74ae49c20a7cd451974e.png{15d18c02628675d0a2c816449d98bda930.pngprivateString str=newString(newchar[100000]);1697e794c86028c5f5b5461ae5ef440a4c.png

    3c6cafce68eb941a00f1998f1d3d3aa6.gifpublicString getSubString(intbegin,intend)9b8a8a44dd1c74ae49c20a7cd451974e.png{17d18c02628675d0a2c816449d98bda930.pngreturnstr.substring(begin, end);18ecedf933ec37d714bd4c2545da43add2.png    }198f1ba5b45633e9678d1db480c16cae3f.png}

    执行此代码结果:

    Exception in thread "main" java.lang.OutOfMemoryError: Java heap space

    问题就出在Huge类的 getSubString 方法,它调用了String类的substring方法。

    来让我们看看 substring 类的实现吧,JDK源码如下:

    1

    1fa987a29c6482f53d401256f96355eb.png

    ca75c07623e1b494fee67e8f316fc310.gifpublicString substring(intbeginIndex,intendIndex)9b8a8a44dd1c74ae49c20a7cd451974e.png{297e794c86028c5f5b5461ae5ef440a4c.png

    3c6cafce68eb941a00f1998f1d3d3aa6.gifif(beginIndex<0)9b8a8a44dd1c74ae49c20a7cd451974e.png{3d18c02628675d0a2c816449d98bda930.pngthrownewStringIndexOutOfBoundsException(beginIndex);4ecedf933ec37d714bd4c2545da43add2.png    }597e794c86028c5f5b5461ae5ef440a4c.png

    3c6cafce68eb941a00f1998f1d3d3aa6.gifif(endIndex>count)9b8a8a44dd1c74ae49c20a7cd451974e.png{6d18c02628675d0a2c816449d98bda930.pngthrownewStringIndexOutOfBoundsException(endIndex);7ecedf933ec37d714bd4c2545da43add2.png    }897e794c86028c5f5b5461ae5ef440a4c.png

    3c6cafce68eb941a00f1998f1d3d3aa6.gifif(beginIndex>endIndex)9b8a8a44dd1c74ae49c20a7cd451974e.png{9d18c02628675d0a2c816449d98bda930.pngthrownewStringIndexOutOfBoundsException(endIndex-beginIndex);10ecedf933ec37d714bd4c2545da43add2.png    }11d18c02628675d0a2c816449d98bda930.pngreturn((beginIndex==0)&&(endIndex==count))?this:12d18c02628675d0a2c816449d98bda930.pngnewString(offset+beginIndex, endIndex-beginIndex, value);138f1ba5b45633e9678d1db480c16cae3f.png    }

    再让我们接下来看看 new String(offset + beginIndex, endIndex - beginIndex, value); 的实现:

    1

    4f1150b881333f12a311ae9ef34da474.png//Package private constructor which shares value array for speed.21fa987a29c6482f53d401256f96355eb.png

    ca75c07623e1b494fee67e8f316fc310.gifString(intoffset,intcount,charvalue[])9b8a8a44dd1c74ae49c20a7cd451974e.png{3d18c02628675d0a2c816449d98bda930.pngthis.value=value;4d18c02628675d0a2c816449d98bda930.pngthis.offset=offset;5d18c02628675d0a2c816449d98bda930.pngthis.count=count;68f1ba5b45633e9678d1db480c16cae3f.png    }

    char[] value 数组被共享了。

    在我们的main函数里的循环中,每循环一次后,我们希望Huge对象被回收,且释放它占有的内存。

    但实际上 private String str = new String(new char[100000]); 占有的内存并不会被释放。

    因为 我们通过 Huge 类的 getSubString 方法得到的 String 对象还存在(存在于handler的列表中),

    它虽然是 length 只有 4 的对象,却享有着 char[100000] 的空间。

    解决方案:

    可以修改Huge 类的 getSubString 方法如下:

    1

    1fa987a29c6482f53d401256f96355eb.png

    ca75c07623e1b494fee67e8f316fc310.gifpublicString getSubString(intbegin,intend)9b8a8a44dd1c74ae49c20a7cd451974e.png{2d18c02628675d0a2c816449d98bda930.pngreturnnewString(str.substring(begin, end));38f1ba5b45633e9678d1db480c16cae3f.png    }

    只要再套一个String的构造方法即可。

    至于为什么,看看JDK源码,一看便知了。这里就不贴出来了。

    唉,以后写代码得多多小心啊。

    ----2010年08月27日

    本文为原创,欢迎转载,转载请注明出处BlogJava。

    展开全文
  • java内存泄露内存溢出基本概念内存泄露:指程序中动态分配内存给一些临时对象,但是对象不会被GC所回收,它始终占用内存。即被分配的对象可达但已无用。内存溢出:指程序运行过程中无法申请到足够的内存导致的一...
  • 在这个相关的技巧中,我将带您了解嵌套类的陷阱之一,这是内部类在JVM中导致内存泄漏和内存不足错误的潜力。 之所以会发生这种类型的内存泄漏,是因为内部类必须始终能够访问其外部类-并非总是与JVM的计划一起使用。...
  • Java中的内存泄漏

    2021-02-13 01:29:04
    比如,长生命周期的对象持有短生命周期对象的引用就很可能发生内存泄漏,尽管短生命周期对象已经不再需要,但是因为长生命周期持有它的引用而导致不能被回收,这就是Java内存泄漏的发生场景。所有的内存泄露,最后...
  • Java内存泄露如何排查

    2021-02-13 00:04:07
    Java内存泄露是常常出现的问题,Java攀登网进行了该问题的整理...在 Java中,内存泄漏就是存在一些被分配的对象,这些对象有下面两个特点:1)首先,这些 对象是可达的,即在有向图中,存在通路可以与其相连;2)其次...
  • java内存泄露8种情况的总结

    万次阅读 多人点赞 2019-04-18 20:41:36
    由于java的JVM引入了垃圾...那么对于这种情况下,由于代码的实现不同就会出现很多种内存泄漏问题(让JVM误以为此对象还在引用中,无法回收,造成内存泄漏)。 1、静态集合类,如HashMap、LinkedList等等。如果这些...
  • 然而,实际的情况并没有那么简单,因为内存泄漏Java应用程序中还是时有发生的。下面就解释下什么是内存泄漏,它为什么会发生,以及我们如何阻止它的发生。1. 什么是内存泄漏内存泄漏的定义:对象已经没有被应用...
  • java导致内存泄露的原因很明确:长生命周期的对象持有短生命周期对象的引用就很可能发生内存泄露,尽管短生命周期对象已经不再需要, 但是因为长生命周期对象持有它的引用而导致不能被回收,这就是java中内存泄露的...
  • 但是,即使这样,Java也还是存在着内存泄漏的情况,1、长生命周期的对象持有短生命周期对象的引用就很可能发生内存泄露。尽管短生命周期对象已经不再需要,但是因为长生命周期对象持有它的引用而导致不能被回收,这...
  • 我想回应Vilx关于事件的评论,并推荐一种有助于解决它的设计模式 .假设你有一个类型是事件源,例如:interface IEventSource{event EventHandler SomethingHappened;}这是一个类的片段,用于处理来自该类型实例的...
  • 但是JAVA中还是存在着许多内存泄露的可能性,如果不好好处理内存泄露,会导致APP内存单元无法释放被浪费掉,最终导致内存全部占据堆栈(heap)挤爆进而程序崩溃。内存泄露说到内存泄露,就不得不提到内存溢出,这两个...
  • 尽管HashMap使用非常方便,但是如果使用不当,可能会导致内存泄漏的。以下章节将介绍 HashMap可能导致内存泄漏的情况,以及如何解决该问题。1. HashMap 的存储首先,我们先明确HashMap的内部是如何存储数据的。...
  • JAVA内存泄露检测工具如何使用在cmd执行:java -Xmx1000m -jar ha404.jarHeapAnalyzer 是 IBM 的一个用来分析 Java 程序的内存堆使用情况的图形化工具。IBM HeapAnalyzer怎么用?IBM HeapAnalyzer,下载之后首先阅读...
  • 我在某些框架API调用BufferedImage.getGraphics()方法时遇到问题,从而导致内存泄漏。此方法的作用是始终调用BufferedImage.createGraphics()。在Windows计算机上,createGraphics()由Win32GraphicsEnvironment处理...
  • 在使用java内部类的时候要注意可能引起的内存泄漏 代码如下 package com.example; public class MyClass { public static void main(String[] args) throws Throwable { } public class A{ public void ...
  • 内存溢出 out of memory,是指程序在申请内存时,没有足够的内存空间供其使用,出现out of memory;内存泄露 memory leak,是指程序在申请内存后,无法释放...以发生的方式来分类,内存泄漏可以分为4类:1. 常发性内...
  • 长生命周期的对象持有短生命周期对象的引用就很可能发生内存泄漏,尽管短生命周期对象已经不再需要,但是因为长生命周期持有它的引用而导致不能被回收,这就是Java内存泄漏的发生场景。造成内存泄漏的几种情况:1...
  • java内存泄漏与处理

    2021-03-10 06:27:31
    内存溢出 out of memory,是指程序在申请内存时,没有足够的内存空间供其使用,出现out of memory;内存泄露 memory leak,是指程序在申请内存后,无法...以发生的方式来分类,内存泄漏可以分为4类:常发性内存泄漏...
  • 但是,即使这样,Java也还是存在着内存泄漏的情况, 长生命周期的对象持有短生命周期对象的引用就很可能发生内存泄露。 尽管短生命周期对象已经不再需要,但是因为长生命周期对象持有它的引用而导致不能被回收,...
  • 内存溢出 out of memory...内存泄露 memory leak,是指程序在申请内存后,无法释放已申请的内存空间,一次内存泄露危害可以忽略,但内存泄露堆积后果很严重,无论多少内存,迟早会被占光。memory leak会最终会导致out...
  • 小心踩雷,一次Java内存泄漏排查实战

    千次阅读 多人点赞 2019-06-04 08:45:00
    找到内存泄漏的对象了,在项目里全局搜索对象名,它是一个 Bean 对象,然后定位到它的一个类型为 Map 的属性。   这个 Map 根据类型用 ArrayList 存储了每次探测接口响应的结果,每次探测完都塞到 ArrayList ...
  • 当一个对象已经不需要再使用本该被回收时,另外一个正在使用的对象持有它的引用从而导致它不能被回收,这导致本该被回收的对象不能被回收而停留在堆内存中,这就产生了内存泄漏内存泄漏对程序的影响? 内存泄漏...

空空如也

空空如也

1 2 3 4 5 ... 20
收藏数 103,309
精华内容 41,323
关键字:

java导致内存泄漏吗

java 订阅