精华内容
下载资源
问答
  • 文章目录Java-排查内存泄漏内存溢出和内存泄露内存溢出产生原因:发生场景此错误常见的错误提示:解决方法内存泄露内存溢出和内存泄露的联系 内存溢出和内存泄露 内存溢出:程序所写入数据的空间大于所申请的空间,...

    Java-内存溢出和内存泄露

    Java-内存泄漏


    内存溢出和内存泄露

    内存溢出:程序所写入数据的空间大于所申请的空间,就会出现溢出。
    内存泄漏:程序用new申请了一块内存,后来很长时间都不再使用了(按理应该释放),但是因为一直被某个或某些实例所持有导致 GC 不能回收,也就是该被释放的对象没有释放。

    内存溢出

    java.lang.OutOfMemoryError,是指程序在申请内存时,没有足够的内存空间供其使用,出现OutOfMemoryError(OOM)。

    产生原因

    1.JVM内存过小。
    2.程序不严密,产生了过多的垃圾。

    发生场景

    1.内存中加载的数据量过于庞大,如一次从数据库取出过多数据。
    2.集合类中有对对象的引用,使用完后未清空,使得JVM不能回收。
    3.代码中存在死循环或循环产生过多重复的对象实体。
    4.使用的第三方软件中的BUG。
    5.启动参数内存值设定的过小。

    此错误常见的错误提示:

    tomcat:java.lang.OutOfMemoryError: PermGen space
    tomcat:java.lang.OutOfMemoryError: Java heap space
    weblogic:Root cause of ServletException java.lang.OutOfMemoryError
    resin:java.lang.OutOfMemoryError
    java:java.lang.OutOfMemoryError
    

    解决方法

    1.增加JVM的内存大小;
    2.修改tomcat容器的JAVA_OPTS参数;

    找到tomcat在电脑中的安装目录,进入这个目录,然后进入bin目录中,在window环境下找到bin目录中的catalina.bat,在linux环境下找到catalina.sh。
    编辑catalina.bat文件,找到JAVA_OPTS(具体来说是 set “JAVA_OPTS=%JAVA_OPTS%
    %LOGGING_MANAGER%”)这个选项的位置,这个参数是Java启动的时候,需要的启动参数。
    也可以在操作系统的环境变量中对JAVA_OPTS进行设置,因为tomcat在启动的时候,也会读取操作系统中的环境变量的值,进行加载。
    如果是修改了操作系统的环境变量,需要重启机器,再重启tomcat,如果修改的是tomcat配置文件,需要将配置文件保存,然后重启tomcat,设置就能生效了。

    3.优化程序,释放垃圾。

    避免死循环,防止一次载入太多的数据,提高程序健壮型及时释放。因此,从根本上解决Java内存溢出的唯一方法就是修改程序,及时地释放没用的对象,释放内存空间。

    内存泄露

    内存泄露(Memory Leak),是指程序在申请内存后,无法释放已申请的内存空间,一次内存泄露危害可以忽略,但内存泄露堆积后果很严重,无论多少内存,迟早会被占光。

    在Java中,内存泄漏就是存在一些被分配的对象,这些对象有下面两个特点: 1)首先,这些对象是可达的,即在有向图中,存在通路可以与其相连;
    2)其次,这些对象是无用的,即程序以后不会再使用这些对象。
    如果对象满足这两个条件,这些对象就可以判定为Java中的内存泄漏,这些对象不会被GC所回收,然而它却占用内存。

    内存溢出和内存泄露的联系

    内存泄露会最终会导致内存溢出。
    相同点:
    都会导致应用程序运行出现问题,性能下降或挂起。
    不同点:
    1.内存泄露是导致内存溢出的原因之一,内存泄露积累起来将导致内存溢出;
    2.内存泄露可以通过完善代码来避免,内存溢出可以通过调整配置来减少发生频率,但无法彻底避免。

    展开全文
  • 内存泄露和内存溢出

    2020-12-14 17:25:25
    最近排查项目组问题的时候,收到了一些页面卡顿和内存溢出的问题,写一篇文章复习下内存泄露和内存溢出的知识。 内存泄露:程序使用一块内存,但是并没有释放它,通过堆积最终导致内存溢出。通常是存在一些无法被GC...

    内存泄露和内存溢出

    最近排查项目组问题的时候,收到了一些页面卡顿和内存溢出的问题,写一篇文章复习下内存泄露和内存溢出的知识。

    内存泄露:程序使用一块内存,但是并没有释放它,通过堆积最终导致内存溢出。通常是存在一些无法被GC回收的对象,这些对象没有作用,却会一致占用内存。内存泄露是代码层面的问题,可以通过修改我们的程序来避免。

    内存溢出:即程序在申请内存的时候,发现内存不够了。通常是因为JVM设置的内存过小、没有释放资源、一次性加载过多数据等等。解决办法可以分为两种:一是增大JVM内存,二是修改我们的程序,从根本上解决问题。

    内存泄露会导致内存溢出,内存泄露的主要原因是代码层面的,所以提高我们程序的健壮性就很重要了。

    展开全文
  • java 内存溢出排查

    千次阅读 2018-05-26 20:28:16
    首先说下:内存溢出和内存泄露 内存溢出:out of memory 是指程序申请内存时没有足够的空间了 内存泄露: memroy leak,是指程序申请内存后,无法释放已申请的内存空间。 内存泄露-》内存溢出 堆内存溢出: 排查...

    1,Java内存溢出包括:堆内存溢出和栈内存溢出

    首先说下:内存溢出和内存泄露

    内存溢出:out of memory 是指程序申请内存时没有足够的空间了

    内存泄露: memroy leak,是指程序申请内存后,无法释放已申请的内存空间。

    内存泄露-》内存溢出

    堆内存溢出:

    排查方法:mat(memory analyzer tool)

    -vmargs:后面跟VM参数

    -Xms20M     -Xmx20M 堆内存的设置

    -XX:PermSize = 40M 非堆内存

    -XX:HeapDumpOnOutOfMemoryError :让虚拟机出现内存溢出时dump出此时的堆内存转储快照。

    -XX:HeapDumpOnCtrBreak

    -xss 设置栈内存

    获取转存储文件的方法:

    1.任务管理器

    2.jvisiualVM工具

    3.jmp,jconsole,jhat工具

    mat 查看内存使用情况

    (1)整体内存的消耗情况(overview)

    (2)分析可以对象

     

    优化从两个层面上来优化:

    (1)非代码层面:-Xms  -Xmx

    (2)代码层面

    内存溢出的几种方式:

    一. java堆溢出

    创建对象没有及时回收,

    1. dump出来堆转储快照 2. 使用MAT工具对dump出来的堆转储快照进行分析,重点是确认内存中得对象是否必要的,这样可以分清楚到底是出现了内存泄露(Memory Leak)还是内存溢出(Memory Overflow) 

    3. 如果是内存泄露,进一步通过MAT工具分析泄露对象到GC Roots的引用链。找到泄露对象是通过怎样的路径与GC Roots相关联并导致垃圾收集器无法自动回收的。 4. 如果不存在泄露,那么就是内存中得对象却是都还必须活着,就应当检查虚拟机的堆参数(-Xmx与-Xms),与机器物理内存对比看是否可以调大

    二. 虚拟机和本地方法栈溢出

     

    在单线程下,无论是由于栈帧太小还是虚拟机栈容量太小,当内存无法分配的时候,虚拟机抛出的都是StackOverflowError异常。 在多线程下,通过不断的建立线程的方式可以产生内存溢出OutOfMemoryError异常。

    在多线程情况下,给每个线程分配的内存越大,越容易产生内存溢出异常。由于操作系统分配给每个进程的内存是有限的,32位的Windows限制为2GB。虚拟机提供了参数来控制Java堆和方法区的这两部分内存的最大值。剩余的2GB减去Xmx,再减去MaxPermSize,忽略掉很小的程序计数器内存。如果虚拟机进程本身耗费的内存不计算,剩下的内存就是有虚拟机栈和本地方法栈瓜分了。此时如果每个线程分配到的虚拟机栈容量越大,可以建立的线程数量自然就越少,建立线程时就越容易把剩下的内存耗尽。 如果建立过多线程导致的内存溢出,在不能减少线程数或者更换64位虚拟机的情况下,就只能通过减少最大堆或者减少栈容量来获取更多的线程。

    出现StackOverflowError的时候有错误堆栈可以读,即时加入+HeapDumpOnOutOfMemoryError也不会dump异常堆内存。

     

    三.   运行时常量池溢出(PermGen space)

     

     

    如果要项运行时常量池中添加内容,最简单的方法就是使用String.intern()这个Native方法。

    异常信息:

    四. 方法区溢出

     

    方法区用于存放Class的相关信息,如类名、访问修饰符、常量池、字段描述、方法描述等。当大量的类产生时填满方法区,会造成方法去溢出。

    方法区溢出也是一种常见内存溢出异常,一个类如果要被垃圾收集器回收,判断条件非常苛刻。

      

     

    展开全文
  • 内存泄露 memory leak:是指程序在申请内存后,无法释放已申请的内存空间,一次内存泄露危害可以忽略,但内存泄露堆积后果很严重,无论多少内存,迟早会被占光。memory leak会最终会导致out of memory!内存泄漏从...

    内存溢出 out of memory:

    是指程序在申请内存时,没有足够的内存空间供其使用,出现out of memory;

    内存泄露 memory leak:

    是指程序在申请内存后,无法释放已申请的内存空间,一次内存泄露危害可以忽略,但内存泄露堆积后果很严重,无论多少内存,迟早会被占光。

    memory leak会最终会导致out of memory!

    内存泄漏从用户的角度来考虑的话根本感觉不到,但是从程序设计的角度我们必须考虑这个问题,因为内存泄漏的堆积最终会消耗系统所有的内存。

    内存泄漏的原因:

    内存泄露是指无用对象(不再使用的对象)持续占有内存或无用对象的内存得不到及时释放,从而造成的内存空间的浪费称为内存泄露,通常是长生命周期的对象持有短生命周期对象的引用就会导致内存泄漏。

    通常有以下几种内存泄漏的场景。

    1.静态集合类引起内存泄露: 如果仅仅释放引用本身(o=null),那么list仍然引用该对象,所以这个对象对GC 来说是不可回收的。

    LinkedList list=new LinkedList<>();int i=0;while(true) {

    Integer o=new Integer(i++);

    list.add(o);

    o=null;

    }

    2.集合里面对象的属性被修改以后,remove方法不起作用

    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);

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

    set.remove(p3);//这个移除是不会发生作用的

    3.数据库,sockect,io等连接没有及时关闭的也会造成内存泄漏,所以需要我们显式的close。

    4.单例模式中,如果单例对象持有外部对象的引用的话,也会导致外部对象不能被回收。

    5.监听器(未解决)

    6.在使用线程池的时候:如果没有去给队列设置固定的长度或者没有给线程池设置规定的个数的话。

    在流量峰值,大量的请求进入的时候,会导致队列塞满或者创建大量的线程,也会导致内存溢出。

    主要发生OOM的就是Heap space(堆空间) 元空间

    常见的一些错误类型:

    1.java.lang.OutOfMemoryError:GC overhead limit exceeded

    默认情况下,当应用程序花费超过98%的时间用来做GC并且回收了不到2%的堆内存时,会抛出java.lang.OutOfMemoryError:GC overhead limit exceeded错误。具体的表现就是你的应用几乎耗尽所有可用内存,并且GC多次均未能清理干净。(就是用了CPU大部分时间去GC,却只回收了2%的内存)

    2.java.lang.OutOfMemoryError:Permgen space

    元空间如何出现内存溢出的情况:

    主要原因就是有太多的类或者太大的类被加载到了元空间中。

    元空间溢出一般在三个时刻:

    初始化的时候:

    一开始的时候就有大量的类或者太大的类被加载到元空间中了。

    这种情况需要我们修改应用程序的启动配置,去增加参数-XX:MaxMetasize的大小

    重新部署的时候:

    在从服务器卸载应用程序时,当前的classloader以及加载的class在没有实例引用的情况下,持久代的内存空间会被GC清理并回收。

    许多第三方库以及糟糕的资源处理方式(比如:线程、JDBC驱动程序、文件系统句柄)使得卸载以前使用的类加载器变成了一件不可能的事。反过来就意味着在每次重新部署过程中,应用程序所有的类的先前版本将仍然驻留在Permgen区中,你的每次部署都将生成几十甚至几百M的垃圾。

    就以线程和JDBC驱动来说说。很多人都会使用线程来处理一下周期性或者耗时较长的任务,这个时候一定要注意线程的生命周期问题,你需要确保线程不能比你的应用程序活得还长。否则,如果应用程序已经被卸载,线程还在继续运行,这个线程通常会维持对应用程序的classloader的引用,造成的结果就不再多说。多说一句,开发者有责任处理好这个问题,特别是如果你是第三方库的提供者的话,一定要提供线程关闭接口来处理清理工作。

    很多人都会使用线程来处理一下周期性或者耗时较长的任务,这个时候一定要注意线程的生命周期问题,你需要确保线程不能比你的应用程序活得还长。否则,如果应用程序已经被卸载,线程还在继续运行,这个线程通常会维持对应用程序的classloader的引用。类就无法被回收。

    解决这个问题主要是分析dump文件,找到引用在哪里被持有的,然后在应用程序卸载的时候把这个引用移除。jmap -dump....

    运行时的oom:

    主要是我们在程序的运行过程中创建了大量的类但其实它的生命周期并不长。

    在没有实例引用的时候

    --XX:+CMSClassUnloadingEnable(默认这个配置是未启用的),GC会扫描这个区并清理不再用的类。我们也需要配合 --XX:+UseConcMarkSweepGC 清除算法。

    在确保JVM可以卸载类的情况下,拿到堆存储文件,分析应该被卸载却没有被卸载的类加载器,然后对该类加载器加载的类进行排查。

    3.java.lang.OutOfMemoryError:Unable to create new native thread

    就是创建太多的线程导致的堆栈溢出:

    主要需要我们排查线程池中的线程的数量是否合适

    4.java.lang.OutOfMemoryError:Out of swap space

    java应用程序在启动时会指定所需要的内存大小,可以通过-Xmx和其他类似的启动参数来指定。在JVM请求的总内存大于可用物理内存的情况下,操作系统会将内存中的数据交换到磁盘上去。

    Out of swap space?表示交换空间也将耗尽,并且由于缺少物理内存和交换空间,再次尝试分配内存也将失败。

    这个问题一般是操作系统级别问题引起的。

    但是我们可以优化我们的代码,减少它的内存占用

    5.java.lang.OutOfMemoryError:Requested array size exceeds VM limit

    当你遇到Requested array size exceeds VM limit错误时,意味着你的应用程序试图分配大于Java虚拟机可以支持的数组。

    6.Out of memory:Kill process or sacrifice child

    当可用虚拟虚拟内存(包括交换空间)消耗到让整个操作系统面临风险时,就会产生Out of memory:Kill process or sacrifice child错误。在这种情况下,OOM Killer会选择“流氓进程”并杀死它。

    直接内存的回收过程

    直接内存虽然不是 JVM 内存空间,但它的垃圾回收也由 JVM 负责。

    垃圾收集进行时,虚拟机虽然会对直接内存进行回收,

    但是直接内存却不能像新生代、老年代那样,发现空间不足了就通知收集器进行垃圾回收,

    它只能等老年代满了后 Full GC,然后“顺便”帮它清理掉内存的废弃对象。

    否则只能一直等到抛出内存溢出异常时,先 catch 掉,再在 catch 块里大喊 “System.gc()”。

    要是虚拟机还是不听,那就只能眼睁睁看着堆中还有许多空闲内存,自己却不得不抛出内存溢出异常了。

    参考:

    展开全文
  • 什么是OOM?就是我们常见的:java.lang.OutOfMemoryError,在应用开发中,是比较常见的一种异常,主要分为三种:OutOfMemoryError:PermGen spaceOutOfMemoryError:Java heap ... 内存溢出 的...
  • 基础内存泄露(Memory Leak)java中内存都是由jvm管理,垃圾回收由gc负责,所以一般情况下不会出现内存泄露问题,所以容易被大家忽略。内存泄漏是指无用对象(不再使用的对象)持续占有内存或无用对象...主要和溢出做区...
  • 基础内存泄露(Memory Leak)java中内存都是由jvm管理,垃圾回收由gc负责,所以一般情况下不会出现内存泄露问题,所以容易被大家忽略。内存泄漏是指无用对象(不再使用的对象)持续占有内存或无用...主要和溢出做区...
  • 基础内存泄露(Memory Leak)java中内存都是由jvm管理,垃圾回收由gc负责,所以一般情况下不会出现内存泄露问题,所以容易被大家忽略。内存泄漏是指无用对象(不再使用的对象)持续占有内存或无用对象...主要和溢出做区...
  • Java内存溢出和泄漏的排查

    千次阅读 2019-06-19 10:04:53
    一定是有一个项目在跑着,然后突然变慢了,你才会想到排查内存泄露的问题的。作为小白,写写逻辑,我觉得基本上接触不到这个问题。自己写程序报错OOM,那需要很大的代码错误。 我接触到这个问题是上次项目经理面试...
  • 面试官:说一下内存溢出排查过程工具?我... 如何使用MAT进行内存泄露分析 Java线上内存溢出问题排查步骤 1、使用top对当前服务器内存有个大致了解,top后 shift+M俺内存占用由大到小排序 2、利用ps命令查看服务...
  • 内存泄露问题排查

    2020-05-29 17:51:08
    一、 内存溢出和内存泄露 a) 内存溢出:内存溢出是在内存一定的情况下,系统申请内存大于预设定内存;可以通过调整最大内存改善这种问题 b) 内存泄露:是由于系统bug导致创建的对象无法正常回收,这种智能通过修改...
  • java内存泄露排查总结

    2021-01-18 11:14:24
    1.内存溢出和内存泄露 一种通俗的说法: 内存溢出:你申请了10个字节的空间,但是你在这个空间写入了11个或者以上字节的数据,则出现溢出 内存泄露:你用new申请了一块内存,后来很长时间都不使用了,但是因为...
  • 自动内存管理是Java区别于C , C++ 的一个重要特性,因为Java程序员把控制内存的权利交给了Java虚拟机,Java程序就不容易出现内存泄露和内存溢出,但是如果出现内存溢出和内存泄漏就不容易排查出错误,了解Java...
  • 对于java程序员来说,虚拟机自动内存管理机制帮助javer们管理内存,不需要再delete/free,不容易出现内存泄漏和溢出问题,也正因为如此,一旦出现了泄露和溢出,如果不了解虚拟机是如何使用内存的,那么排查将非常艰难....
  • Linux内存泄露溢出

    2015-09-01 11:04:40
    下面是排查和解决方案与大家一起分享。 1、Linux 内存监控内存泄漏的定义: 一般我们常说的内存泄漏是指堆内存的泄漏。堆内存是指程式从堆中分配的,大小任意的(内存块的大小能够在程式运行期决定),使用完后...
  • 进而不容易出现内存泄露和内存溢出的问题,由虚拟机管理内存,貌似这一切看起来很好。也正是因为java程序员把内存控制的权利交给了java虚拟机,一旦出现内存泄露和溢出的问题,假如不了解虚拟机是怎样使用内存,排查...
  • 对于Java开发人员来讲,在虚拟机自动内存管理机制的帮助下,不需要为每一个new操作去...正是因为JVM管理内存控制的权利,一旦出现内存泄露和内存溢出的问题,如果不了解JVM是怎样使用内存的,排查错误将变得异常困难。
  • 第二章 Java内存区域与内存溢出异常 一、概述 对与Java程序员来说,在虚拟机自动...但是一旦出现内存泄露和内存溢出问题,如果不了解虚拟机是怎么使用内存的,那么排查错误将会成为 一项异常艰难的工作。 二、...
  • Java内存区域与内存溢出异常 1.概述 对于 Java 的开发者来说,...不过,也正是因为这样,一旦出现内存泄露和溢出方面的问题,如果不了解虚拟机是怎样使用内存的,那么排查错误将会异常艰难。 所以我们只有了解
  • 概述 对于Java程序员来说,在虚拟机自动内存管理机制的帮助... 不过,也正是因为Java程序员把内存控制的权利交给了Java虚拟机,一旦出现内存泄露和溢出方面的问题,如果不了解虚拟机是怎样使用内存的,那么排查错误将
  • 由于java的虚拟机自动内存管理机制,所以我们大部分情况下不会出现内存泄露和内存溢出的问题,但一旦出现,还是的有排查异常解决问题的能力,这里就需要理解虚拟机是怎么使用内存的。 这一章主要讲的是jvm内存的...
  • Java将内存控制的权利交给了Java虚拟机,一旦出现内存泄露和溢出问题,如果不了解虚拟机是怎样使用内存的,那么排查错误将会成为一项异常艰难的工作。 下面将从概念上介绍Java虚拟机内存的各个区域,说明这些区域的...
  • Java与C++之间有一堵由内存动态分配垃圾收集技术...      - 优点:操作简单,不容易发生内存泄露和内存溢出问题;       - 缺点:一旦出现内存泄露和溢出问题,需要了解虚拟机内存管理的机制来排查错误。 .
  • 由于Finalizable,导致的内存溢出问题的分析和排查处理过程。异常现象分析通过上面的内容可以看到,是应为Finalizer的问题引起的内容泄露,Finalizable对象的生命周期普通对象的行为是完全不同的,列举如下:1、...
  • 对于java程序员来说,在虚拟机自动内存管理机制的帮助下,不再需要为每一个new操作去写配对的delete/free代码,不容易出现内存泄露和内存溢出问题,由虚拟机管理内存这一切看起来都很美好,不过,也正是因为java...
  • 对于java程序员来说,虚拟机自动内存管理机制帮助javer们管理内存,不需要再delete/free,不容易出现内存泄漏和溢出问题,也正因为如此,一旦出现了泄露和溢出,如果不了解虚拟机是如何使用内存的,那么排查将非常艰难....
  • Java程序员把内存控制交给了java虚拟机,一旦出现内存泄露和溢出方面的问题,如果不了解虚拟机是怎样使用内存的,那么排查错误将会成为一项异常艰难的工作,为此,冲冲冲,冲去学习吧! 写的可能不算全面与严谨,...
  • 对于Java程序员来说,在虚拟机自动内存管理机制之下,不再需要手动的为每一个对象分配内存,去写配对的delete/free代码,并且不容易出现内存泄漏和内存溢出的问题。但也正因为java程序员将内存管理的权利交给了...
  • Java与C++中存在的一堵...但是一旦出现内存泄露溢出,如果不了解虚拟机怎样分配内存的,那么排查将非常困难。Java虚拟机将执行java程序过程中管理的内存划分成若干个区域,每个区域有各自的用途以及创建销毁的时

空空如也

空空如也

1 2 3 4 5 ... 10
收藏数 185
精华内容 74
关键字:

内存溢出和内存泄露排查