zoukankan      html  css  js  c++  java
  • 牛客网Java刷题知识点之内存溢出和内存泄漏的概念、区别、内存泄露产生原因、内存溢出产生原因、内存泄露解决方案、内存溢出解决方案

    不多说,直接上干货!

    福利 => 每天都推送 

    欢迎大家,关注微信扫码并加入我的4个微信公众号:   大数据躺过的坑      Java从入门到架构师      人工智能躺过的坑         Java全栈大联盟
     
         每天都有大量的学习视频资料和精彩技术文章推送... 人生不易,唯有努力。
     
         百家号 :九月哥快讯               快手号:  jiuyuege
     
     
     
     
     

    内存溢出和内存泄漏的区别

        内存泄漏指你用malloc或new申请了一块内存,但是没有通过free或delete将内存释放,导致这块内存一直处于占用状态。
        内存溢出指你申请了10个字节的空间,但是你在这个空间写入11或以上字节的数据,就是溢出。

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

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

       内存溢出( out of memory),是指程序在申请内存时,没有足够的内存空间供其使用,出现out of memory;比如申请了一个integer,但给它存了long才能存下的数,那就是内存溢出。
      注意:memory leak会最终会导致out of memory!

            内存泄露最终会导致内存溢出。
      内存溢出就是你要求分配的内存超出了系统能给你的,系统不能满足需求,于是产生溢出。

      相同点:都会导致应用程序运行出现问题,性能下降或挂起。

           不同点

              1) 内存泄露是导致内存溢出的原因之一;内存泄露积累起来将导致内存溢出

              2) 内存泄露可以通过完善代码来避免;内存溢出可以通过调整配置来减少发生频率,但无法彻底避免

    引起内存泄露的原因:

      (1)静态集合类,例如HashMap和Vector。如果这些容器为静态的,由于它们的生命周期与程序一致,那么容器中的对象在程序结束之前将不能被释放,从而造成内存泄露。

      (2)各种连接,例如数据库连接、网络联接以及IO连接等。在对数据库进行操作的过程中,首先需要建立与数据库的连接、当不再使用时,需要调用close方法来释放与数据库的连接。只有连接被关闭后,垃圾回收器才会回收对应的对象。否则,如果在访问数据库的过程中,对Connection、Statement或ResultSet不显示地关闭,将会造成大量的对象无法被回收,从而引起内存泄露。

      (3)监听器。在Java语言中,往往会使用到监听器。通常一个应用中会用到多个监听器。但在释放对象的同时往往没有相应地删除监听器,这也可能导致内存泄露。

      (4)变量不合理的作用域。一般而言,如果一个变量定义的作用范围大于其使用范围,很有可能会造成内存泄露,另一方面如果没有及时地把对象设置为null,很有可能会导致内存泄露的发生。

    引起内存溢出的原因

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

    
    
    
    
    

    内存泄漏可以分为4类

      1)  常发性内存泄漏。发生内存泄漏的代码会被多次执行到,每次被执行的时候都会导致一块内存泄漏。

      2)  偶发性内存泄漏。发生内存泄漏的代码只有在某些特定环境或操作过程下才会发生。常发性和偶发性是相对的。对于特定的环境,偶发性的也许就变成了常发性的。所以测试环境和测试方法对检测内存泄漏至关重要。

      3)  一次性内存泄漏。发生内存泄漏的代码只会被执行一次,或者由于算法上的缺陷,导致总会有一块仅且一块内存发生泄漏。比如,在类的构造函数中分配内存,在析构函数中却没有释放该内存,所以内存泄漏只会发生一次。

      4)  隐式内存泄漏。程序在运行过程中不停的分配内存,但是直到结束的时候才释放内存。严格的说这里并没有发生内存泄漏,因为最终程序释放了所有申请的内存。但是对于一个服务器程序,需要运行几天,几周甚至几个月,不及时释放内存也可能导致最终耗尽系统的所有内存。所以,我们称这类内存泄漏为隐式内存泄漏。

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

        

      一是从代码层面进行优化完善,尽量避免该情况发生;

            二是调整优化服务器配置: 

              1) 设置-Xms、-Xmx相等;

              2)  设置NewSize、MaxNewSize相等;

              3) 设置Heap size, PermGen space:

                Tomcat 的配置示例:修改 %TOMCAT_HOME%/bin/catalina.bat or catalina.sh

                在“echo "Using CATALINA_BASE: $CATALINA_BASE"”上面加入以下行:

    Cmd代码 set JAVA_OPTS=-Xms800m -Xmx800m -XX:PermSize=128M -XX:MaxNewSize=256m -XX:MaxPermSize=256m

    Java中会存在内存泄漏吗?

      Java中也存在内存泄露。当被分配的对象可达但已无用(未对作废数据内存单元的引用置null)即会引起。

    Vector v=new Vector(10);   
    for (int i=1;i<100; i) {   
        Object o=new Object();   
        v.add(o);   
        o=null;   
    }   

      此时,所有的Object对象都没有被释放,因为变量v引用这些对象。   

       对象加入到Vector后,还必须从Vector中删除,最简单释放方法就是将Vector对象设置为null。   

    如何检测内存泄露?   

      可以通过一些性能监测分析工具,如 JProfiler、OptimizeitProfiler。

    如何避免内存泄露、内存溢出?

        1)   尽早释放无用对象的引用。

                    好的办法是使用临时变量的时候,让引用变量在退出活动域后自动设置为null,暗示垃圾收集器来收集该对象,防止发生内存泄露。

             2)   程序进行字符串处理时,尽量避免使用String,而应使用StringBuffer。

                   因为每一个String对象都会独立占用内存一块区域,

        如:

    String str = "aaa";   
    String str2 = "bbb";   
    String str3 = str  str2;   

      假如执行此次之后str , str2再不被调用,那么它们就会在内存中等待GC回收;   

      假如程序中存在过多的类似情况就会出现内存错误;   

       3)   尽量少用静态变量。

               因为静态变量是全局的,GC不会回收。

             4)  避免集中创建对象尤其是大对象,如果可以的话尽量使用流操作。

             JVM会突然需要大量内存,这时会触发GC优化系统内存环境;

        5)  尽量运用对象池技术以提高系统性能。

               生命周期长的对象拥有生命周期短的对象时容易引发内存泄漏,例如大集合对象拥有大数据量的业务对象的时候,可以考虑分块进行处理,然后解决一块释放一块的策略。

             6)  不要在经常调用的方法中创建对象,尤其是忌讳在循环中创建对象。

               可以适当的使用hashtable,vector创建一组对象容器,然后从容器中去取那些对象,而不用每次new之后又丢弃。

            7)   优化配置。
















    欢迎大家,加入我的4个微信公众号:    大数据躺过的坑     Java从入门到架构师    人工智能躺过的坑     Java全栈大联盟    
     
     
     

    同时,大家可以关注我的个人博客

       http://www.cnblogs.com/zlslch/   和     http://www.cnblogs.com/lchzls/      http://www.cnblogs.com/sunnyDream/   

       详情请见:http://www.cnblogs.com/zlslch/p/7473861.html

      人生苦短,我愿分享。本公众号将秉持活到老学到老学习无休止的交流分享开源精神,汇聚于互联网和个人学习工作的精华干货知识,一切来于互联网,反馈回互联网。
      目前研究领域:大数据、机器学习、深度学习、人工智能、数据挖掘、数据分析。 语言涉及:Java、Scala、Python、Shell、Linux等 。同时还涉及平常所使用的手机、电脑和互联网上的使用技巧、问题和实用软件。 只要你一直关注和呆在群里,每天必须有收获

          对应本平台的讨论和答疑QQ群:大数据和人工智能躺过的坑(总群)(161156071) 

     

     

     

         打开百度App,扫码,精彩文章每天更新!欢迎关注我的百家号: 九月哥快讯





  • 相关阅读:
    UOJ #455 [UER #8]雪灾与外卖 (贪心、模拟费用流)
    Codeforces 482E ELCA (LCT)
    Codeforces 798D Mike and distribution (构造)
    AtCoder AGC017C Snuke and Spells
    HDU 6089 Rikka with Terrorist (线段树)
    HDU 6136 Death Podracing (堆)
    AtCoder AGC032D Rotation Sort (DP)
    jenkins+python+kubectl实现批量更新k8s镜像
    Linux 下载最新kubectl版本的命令:
    jenkins X 和k8s CI/CD
  • 原文地址:https://www.cnblogs.com/zlslch/p/7622138.html
Copyright © 2011-2022 走看看