精华内容
下载资源
问答
  • 什么是内存泄漏 指程序中动态分配内存给一些临时对象,但是对象不会被GC所回收,它始终占用内存。即被分配的对象可达但已无用。 造成这种现象的原因要从,jvm内存模型和java GC机制说起 一般局部变量是存在java...

    什么是内存泄漏

    指程序中动态分配内存给一些临时对象,但是对象不会被GC所回收,它始终占用内存。即被分配的对象可达但已无用。

    造成这种现象的原因要从,jvm内存模型和java GC机制说起
    在这里插入图片描述
    一般局部变量是存在java虚拟机栈的栈帧里,在代码里一个方法就会有一个栈帧, new一个对象他会在堆里开辟块内存来存放他的实例,当这个实例赋值给局部变量的时候,就把它们通过动态链接连接上了,这就是常说的栈指向堆。

    当方法执行完成后,栈帧就弹出java虚拟机栈,然后销毁,但之前动态链接指向的对象实例任然会存在在堆内存里。这时就有javaGC的机制来处理这已经不用的对象了。

    结构

    这时说一下堆内存的结构,堆是由新生代和老年代组成,新生代里又有Eden和SurvivorFrom、SurvivorTo区。

    垃圾判断算法

    一般通过这两种算法去判断对象是否存活:1.引用计数法 2.可达性分析算法

    分代收集算法

    分代收集算法分代收集算法严格来说并不是一种思想或理论,而是融合上述3种基础的算法思想,而产生的针对不同情况所采用不同算法的一套组合拳,根据对象存活周期的不同将内存划分为几块。

    新生代中,每次垃圾收集时都发现有大批对象死去,只有少量存活,那就选用复制算法,只需要付出少量存活对象的复制成本就可以完成收集。

    老年代中,因为对象存活率高、没有额外空间对它进行分配担保,就必须使用标记-清理算法或者标记-整理算法来进行回收。

    对象年龄

    虚拟机给每个对象定义了一个对象年龄(Age)计数器,如果对象在Eden出生并经过第一次Minor GC后仍然存活,并且能被Survivor容纳的话,将被移动到Survivor空间中(正常情况下对象会不断的在Survivor的From与To区之间移动),并且对象年龄设为1。对象在Survivor区中每经历一次Minor GC,年龄就增加1岁,当它的年龄增加到一定程度(默认15岁),就将会晋升到老年代中。对象晋升老年代的年龄阈值,可以通过参数 XX:MaxPretenuringThreshold 设置。

    GC流程

    Minor GC
    新new对象的时候会在Eden区开辟内存空间,当Eden区没有足够空间进行分配时,虚拟机会发起一次 Minor GC,此时就会把Eden+SurvivorFrom里面没有非存活的对象都回收调,把存活的对象用复制回收算法放到SurvivorTo区里面(如果From内存不足了,会直接放到老年代里),然后From Survivor和To Survivor的逻辑关系会发生颠倒: From变To , To变From,目的是保证有连续的空间存放对方,避免碎片化的发生。这样第二次Minor GC的时候就会把Eden区存活的对象放到了之前的SurvivorTo里了。

    Full GC
    每一次Minor GC过后,都会往新生代里的Survivor区放还存活的对象,而本身就存在在Survivor区存活的对象则会年龄+1,直到到达年龄最大限制值时(可以通过配置XX:MaxPretenuringThreshold来修改最大年龄限制,此参数默认为15),会通过复制回收算法把对象放到老年代里。当很多次这样的操作之后,老年代内存也写满了,就会触发Full GC了。

    内存泄漏现象详细描述

    内存泄漏现象就是,在开发时,创建完一个对象之后,这个对象在后面的代码里没有再需要用他了,但是却还被之前代码引用着无法释放,他就会先一直存放在新生代的Survivor区里,直达多次Minor GC 让这对象的年龄到达设置的最高值,最终到老年代里,而老年代里的对象是只有老年代写满后触发的Full GC才能回收资源,所以他就一直站着内存不释放,而且程序里也没有再使用他的地方,这样就是内存泄漏。

    内存泄漏处理

    三个方面处理
    1.主要因为代码原因造成的内存泄漏,可以找机器内存里占内存比较多的类,找到用他的方法,优化代码逻辑,及时释放对象的引用。
    2.jvm参数,可以通过增大XX:MaxPretenuringThreshold参数值,让对象更有可能被Minor GC回收掉,但同时得用XX:PretenureSizeThreshold这个参数限制存放在新生代的最大的对象是多少,防止对象在新生区,占用空间大,会由于空间不足而导致很多小对象进入到老年区,最后可以增大Survivor区的内存使用率-XX:TargetSurvivorRatio这个参数(默认为50%),降低进入老年代的频率。
    3.机器根据程序的访问量来保证数量,还得做好负载均衡,防止某一台机器访问量过高,这样也容易造成内存泄漏,当内存泄漏严重的时候,会造成内存溢出,从服务挂掉。

    展开全文
  • 1、什么是内存泄漏 简单地说就是申请了一块内存空间,使用完毕后没有释放掉。它的一般表现方式是程序运行时间越长,占用内存越多,最终用尽全部内存,整个系统崩溃。由程序申请的一块内存,且没有任何一个指针指向它...

    1、什么是内存泄漏

    简单地说就是申请了一块内存空间,使用完毕后没有释放掉。它的一般表现方式是程序运行时间越长,占用内存越多,最终用尽全部内存,整个系统崩溃。由程序申请的一块内存,且没有任何一个指针指向它,那么这块内存就泄露了。

    2、内存泄漏对程序的影响

    内存泄漏是造成应用程序OOM的主要原因之一。我们知道Android系统为每个应用程序分配的内存是有限的,而当一个应用中产生的内存泄漏比较多时,这就难免会导致应用所需要的内存超过系统分配的内存限额,这就造成了内存溢出从而导致应用Crash。

    3、如何检查和分析内存泄漏?

    因为内存泄漏是在堆内存中,所以对我们来说并不是可见的。通常我们可以借助MAT、LeakCanary等工具来检测应用程序是否存在内存泄漏。

    1、MAT是一款强大的内存分析工具,功能繁多而复杂。
    2、LeakCanary则是由Square开源的一款轻量级的第三方内存泄漏检测工具,当检测到程序中产生内存泄漏时,它将以最直观的方式告诉我们哪里产生了内存泄漏和导致谁泄漏了而不能被回收。

    4、内存溢出原因及解决方案

    内存溢出是指应用系统中存在无法回收的内存或使用的内存过多,最终使得程序运行要用到的内存大于虚拟机能提供的最大内存。
    引起内存溢出的原因有很多种,常见的有以下几种:

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

    内存溢出的解决方案:

    • 第一步,修改JVM启动参数,直接增加内存。(-Xms,-Xmx参数一定不要忘记加。)
    • 第二步,检查错误日志,查看“OutOfMemory”错误前是否有其它异常或错误。
    • 第三步,对代码进行走查和分析,找出可能发生内存溢出的位置。
    • 第四步,使用内存查看工具动态查看内存使用情况。

    重点排查以下几点:

    1. 检查对数据库查询中,是否有一次获得全部数据的查询。
      一般来说,如果一次取十万条记录到内存,就可能引起内存溢出。这个问题比较隐蔽,在上线前,数据库中数据较少,不容易出问题,上线后,数据库中数据多了,一次查询就有可能引起内存溢出。因此对于数据库查询尽量采用分页的方式查询。
    2. 检查代码中是否有死循环或递归调用。
    3. 检查是否有大循环重复产生新对象实体。
    4. 检查对数据库查询中,是否有一次获得全部数据的查询。一般来说,如果一次取十万条记录到内存,就可能引起内存溢出。这个问题比较隐蔽,在上线前,数据库中数据较少,不容易出问题,上线后,数据库中数据多了,一次查询就有可能引起内存溢出。因此对于数据库查询尽量采用分页的方式查询。
    5. 检查List、MAP等集合对象是否有使用完后,未清除的问题。List、MAP等集合对象会始终存有对对象的引用,使得这些对象不能被GC回收。
    展开全文
  • 主要介绍了Java中典型的内存泄露问题和解决方法,典型的内存泄露例子是一个没有实现hasCode和equals方法的Key类在HashMap中保存的情况,可以通过实现Key类的equals和hasCode方法解决这种内存泄漏问题,需要的朋友可以...
  • 1. Java 堆空间 发生频率:5颗星 造成原因 无法在 Java 堆中分配对象 吞吐量增加 应用程序无意中保存了对象引用,对象无法被 GC 回收 应用程序过度使用finalizer。...解决方案 单位对应:GB -> G, g;M...

    1. Java 堆空间

    发生频率:5颗星

    造成原因

    • 无法在 Java 堆中分配对象
    • 吞吐量增加
    • 应用程序无意中保存了对象引用,对象无法被 GC 回收
    • 应用程序过度使用finalizer。finalizer 对象不能被 GC 立刻回收。finalizer 由结束队列服务的守护线程调用,有时finalizer 线程的处理能力无法跟上结束队列的增长

    解决方案

    单位对应:GB -> G, g;MB -> M, m;KB -> K, k

    • 使用 -Xmx 增加堆大小
    • 修复应用程序中的内存泄漏

    2. GC 开销超过限制

    发生频率:5颗星

    造成原因

    • Java 进程98%的时间在进行垃圾回收,恢复了不到2%的堆空间,最后连续5个(编译时常量)垃圾回收一直如此。

    解决方案

    • 使用 -Xmx 增加堆大小
    • 使用 -XX:-UseGCOverheadLimit 取消 GC 开销限制
    • 修复应用程序中的内存泄漏

    3. 请求的数组大小超过虚拟机限制

    发生频率:2颗星

    造成原因

    • 应用程序试图分配一个超过堆大小的数组

    解决方案

    • 使用 -Xmx 增加堆大小
    • 修复应用程序中分配巨大数组的 bug

    4. Perm gen 空间

    发生频率:3颗星

    造成原因

    • Perm gen 空间包含:
    • 类的名字、字段、方法
    • 与类相关的对象数组和类型数组
    • JIT 编译器优化

    当 Perm gen 空间用尽时,将抛出异常。

    解决方案

    • 使用 -XX: MaxPermSize 增加 Permgen 大小
    • 不重启应用部署应用程序可能会导致此问题。重启 JVM 解决

    5. Metaspace

    发生频率:3颗星

    造成原因

    • 从 Java 8 开始 Perm gen 改成了 Metaspace,在本机内存中分配 class 元数据(称为 metaspace)。如果 metaspace 耗尽,则抛出异常
      解决方案
    • 通过命令行设置 -XX: MaxMetaSpaceSize 增加 metaspace 大小
    • 取消 -XX: maxmetsspacedize
    • 减小 Java 堆大小,为 MetaSpace 提供更多的可用空间
    • 为服务器分配更多的内存
    • 可能是应用程序 bug,修复 bug

    6. 无法新建本机线程

    发生频率:5颗星

    造成原因

    • 内存不足,无法创建新线程。由于线程在本机内存中创建,报告这个错误表明本机内存空间不足
      解决方案
    • 为机器分配更多的内存
    • 减少 Java 堆空间
    • 修复应用程序中的线程泄漏。
    • 增加操作系统级别的限制
    • ulimit -a
    • 用户进程数增大 (-u) 1800
    • 使用 -Xss 减小线程堆栈大小

    7. 杀死进程或子进程

    发生频率:1颗星

    造成原因

    • 内核任务:内存不足结束器,在可用内存极低的情况下会杀死进程
      解决方案
    • 将进程迁移到不同的机器上
    • 给机器增加更多内存

    与其他 OOM 错误不同,这是由操作系统而非 JVM 触发的。

    8. 发生 stack_trace_with_native_method

    发生频率:1颗星

    造成原因

    • 本机方法(native method)分配失败
    • 打印的堆栈跟踪信息,最顶层的帧是本机方法
      解决方案
    • 使用操作系统本地工具进行诊断

    原文链接:
    https://bloggceasy.files.wordpress.com/2015/05/outofmemoryerror2.pdf
    https://mp.weixin.qq.com/s/9h7cpFDEclEup1BMEEzlhw

    展开全文
  • 内存溢出 out of memory,是指程序在申请内存时,没有足够的内存空间供其使用, 出现out of memory;比如申请了一个integer,但给它存了long才能存下... 一次内存泄露危害可以忽略,但内存泄露堆积后果很严重,无论...

        内存溢出 out of memory,是指程序在申请内存时,没有足够的内存空间供其使用,
            出现out of memory;比如申请了一个integer,但给它存了long才能存下的数,那就是内存溢出。

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

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

            内存溢出就是你要求分配的内存超出了系统能给你的,系统不能满足需求,于是产生溢出。
            
            内存泄漏是指你向系统申请分配内存进行使用(new),可是使用完了以后却不归还(delete),结果你申请到
            的那块内存你自己也不能再访问(也许你把它的地址给弄丢了),而系统也不能再次将它分配给需要的程序。
            一个盘子用尽各种方法只能装4个果子,你装了5个,结果掉倒地上不能吃了。这就是溢出!比方说栈,
            栈满时再做进栈必定产生空间溢出,叫上溢,栈空时再做退栈也产生空间溢出,称为下溢。
            就是分配的内存不足以放下数据项序列,称为内存溢出. 

           以发生的方式来分类,内存泄漏可以分为4类: 

            1. 常发性内存泄漏。发生内存泄漏的代码会被多次执行到,每次被执行的时候都会导致一块内存泄漏。 
            2. 偶发性内存泄漏。发生内存泄漏的代码只有在某些特定环境或操作过程下才会发生。
               常发性和偶发性是相对的。对于特定的环境,偶发性的也许就变成了常发性的。
               所以测试环境和测试方法对检测内存泄漏至关重要。 
            3. 一次性内存泄漏。发生内存泄漏的代码只会被执行一次,或者由于算法上的缺陷,
               导致总会有一块仅且一块内存发生泄漏。比如,在类的构造函数中分配内存,
               在析构函数中却没有释放该内存,所以内存泄漏只会发生一次。 
            4. 隐式内存泄漏。程序在运行过程中不停的分配内存,但是直到结束的时候才释放内存。
               严格的说这里并没有发生内存泄漏,因为最终程序释放了所有申请的内存。
               但是对于一个服务器程序,需要运行几天,几周甚至几个月,不及时释放内存也可能
               导致最终耗尽系统的所有内存。所以,我们称这类内存泄漏为隐式内存泄漏    

            从用户使用程序的角度来看,内存泄漏本身不会产生什么危害,作为一般的用户,根本感觉不到内存泄漏的存在。
            真正有危害的是内存泄漏的堆积,这会最终消耗尽系统所有的内存。从这个角度来说,一次性内存泄漏并没有什么危害,
            因为它不会堆积,而隐式内存泄漏危害性则非常大,因为较之于常发性和偶发性内存泄漏它更难被检测到 

             
            内存溢出的原因以及解决方法

            引起内存溢出的原因有很多种,小编列举一下常见的有以下几种:

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

            内存溢出的解决方案:

            第一步,修改JVM启动参数,直接增加内存。(-Xms,-Xmx参数一定不要忘记加。)

            第二步,检查错误日志,查看“OutOfMemory”错误前是否有其它异常或错误。

            第三步,对代码进行走查和分析,找出可能发生内存溢出的位置。
                重点排查以下几点:
                1.检查对数据库查询中,是否有一次获得全部数据的查询。一般来说,如果一次取十万条记录到内存,
                  就可能引起内存溢出。这个问题比较隐蔽,在上线前,数据库中数据较少,不容易出问题,上线后,
                  数据库中数据多了,一次查询就有可能引起内存溢出。因此对于数据库查询尽量采用分页的方式查询。

                2.检查代码中是否有死循环或递归调用。

                3.检查是否有大循环重复产生新对象实体。

                4.检查List、MAP等集合对象是否有使用完后,未清除的问题。List、MAP等集合对象会始终存有对对象的引用,使得这些对象不能被GC回收。

            第四步,使用内存查看工具动态查看内存使用情况  (另一章写有关于内存查看工具的使用)      

    展开全文
  • 本文介绍了Java内存溢出的详细解决方案。本文总结内存溢出主要有两种情况,而JVM经常调用垃圾回收器解决内存堆不足的问题,但是有时...作者分析了JVM内存区域组成及JVM设置虚拟内存的方式,从而给出了一系列解决方案
  • JVM调优专题-内存溢出及解决方案

    千次阅读 2019-06-29 19:59:30
    吃撑过吗?吃多了还想吃咋办? 当然JVM也有吃撑了的时候,甚至撑到程序宕机卡死,后果很严重。本节我们一起探讨如何判断JVM内存溢出、以及其解决方案
  • 文章目录一、概念的区分二、内存溢出的原因以及解决方法2.1、内存溢出的原因2.2、内存溢出的解决方案:三、内存泄漏3.1、内存泄漏的分类:3.2、内存泄漏的危害 一、概念的区分 内存溢出 out of memory,是指程序在...
  • 前言Java通过垃圾回收机制,可以自动的管理内存,这对开发人员来说是多么美好的事啊。但垃圾回收器并不是万能的,它能够处理大部分场景下的内存清理、内存泄露以及内存优化。但它也并不是万能的。不...
  • 内存泄漏 概念: 一个不再被程序使用的对象或者变量还在内存中占有存储空间。 (1)堆中申请的空间没有被释放 (2)对象不在使用但还在内存中保留 内存泄漏的原因: (1)静态集合类,如hashmap和vector,如果...
  • JVM内存泄露解决之道

    2011-12-20 14:57:30
    很好很强大,提供了很好很强大的解决方案。策略比较新颖,值得一下!
  • JVM——内存溢出和内存泄漏的区别

    千次阅读 2018-12-02 21:57:26
    今日本帅博主在研究JVM,今天我们就来游走于内存溢出与内存泄漏之间,且看看它们是个啥,且又有啥子区别。 1.内存溢出和内存泄漏是啥 内存溢出 out of memory,是指程序在申请内存时,没有足够的内存空间供其使用...
  • 前言:JVM中除了程序计数器,其他的...1.内存泄漏和内存溢出区别与联系 内存泄漏:系统分配的内存没有被回收。 内存溢出:分配的内存空间超过系统内存。 2.内存泄漏的原因分析 jvm由5大块组成:堆,栈,本地...
  • JVM - 排查Java内存泄漏

    2019-08-30 17:50:18
    这是一个常见的误解:虽然垃圾收集器做得很好,但即使是最好的程序员也完全有可能成为严重破坏内存泄漏的牺牲品。让我解释一下。 当不必要地维护不再需要的对象引用时,会发生内存泄漏。这些泄漏很糟糕。首先,当...
  • 程序在申请内存后,系统无法释放已申请的内存空间,少量的内存泄露危害可以忽略,但内存泄露慢慢堆积,后果很严重,无论多少内存,迟早会被占光。 内存溢出 (OutOfMemory) 程序在申请内存时,系统没有足够的空间...
  • Java中的内存泄露问题 及解决方法

    万次阅读 2018-08-09 23:35:02
    (Memory Leak,内存泄漏) 为什么会产生内存泄漏? 当一个对象已经不需要再使用本该被回收时,另外一个正在使用的对象持有它的引用从而导致它不能被回收,这导致本该被回收的对象不能被回收而停留在堆内存中,这...
  • 还会涉及到Java JVM内存泄漏溢出等 MySQL数据库优化:分库分表、慢查询、长事务的优化等 阿里P8架构师谈:MySQL慢查询优化、索引优化、以及表等优化总结 阿里P8架构师谈:架构设计之数据库垂直、水平拆分六...
  • 在虚拟机自动内存管理机制的帮助下,不需要自己实现释放内存,不容易出现内存泄漏和内存溢出的问题,由虚拟机管理内存这一切看起来非常美好,但是一旦出现内存溢出或者内存泄漏的问题,对于不熟悉jvm虚拟机是怎么...
  • 详解:Flutter内存泄漏解决方案

    千次阅读 2020-10-15 16:20:00
    背景众所周知,内存的高低是评判一款app的性能优劣的重要的指标之一。如何更简单的帮助开发者分析、暴露且解决内存泄漏问题,几乎是每一个平台或框架、开发者亟需的一个的"标配"...
  • 内存溢出和内存泄漏 内存溢出 out of memory,是指程序在申请内存时,没有足够的内存空间供其使用,出现out of memory;比如申请了一个integer,但给它存了long才能存下的数,那就是内存溢出。 内存泄露 memory leak...
  • 开发中遇到过以下三种内存溢出的状况: 一、 java.lang.OutOfMemoryError: Java heap space 二、 java.lang.OutOfMemoryError: PermGen space 三、 java.lang.OutOfMemoryError: GC overhead limit exceeded ...
  • 内存泄漏问题解决,项目如期上线~ 最后 对于内存泄漏导致的内存溢出问题,排查步骤大致如上述,总的步骤:找出问题(GC、CPU、磁盘、内存、网络),定位问题(使用第三方工具分析dump文件等),解决问题;...
  • Java内存泄露内存无法回收解决方案,深入讲解相关原理及相关过程。
  • 但垃圾回收器并不是万能的,它能够处理大部分场景下的内存清理、内存泄露以及内存优化。但它也并不是万能的。 不然,我们在实践的过程中也不会出现那么多因内存泄露导致的生产事件了。但很多内存泄露时间也是因为...
  • java内存泄露问题的定位与详细的分析过程
  • 造成OutOfMemoryError内存泄露典型原因对象已经死了 无法通过垃圾收 集器进行自动回收 需要通过找出泄露的代码位置和原因 才好确定解决方案 分析步骤 1用工具生成java应用程序的 heapdump (如jmap) 2. 使用 Java ...
  • hibernate QueryPlanCache引发的JVM内存泄漏 一、生产环境问题现象 一个经手多人的项目,项目中用到了hibernate作为ORM框架。生产环境中会出现HeapUsage持续缓慢上升的情况,导致出现HeapUsage超过80%的告警(见图1...

空空如也

空空如也

1 2 3 4 5 ... 20
收藏数 22,356
精华内容 8,942
关键字:

jvm内存泄漏解决方案