精华内容
下载资源
问答
  • 内存泄漏:应用程序不再需要的内存,由于某种原因,内存没有返回到操作系统或可用内存池中。 原因 1.意外的全局变量 JS在处理未声明的变量时,对未声明的变量的引用会在全局对象内创建一个新变量。这些全局变量是...

    定义

    内存泄漏:应用程序不再需要的内存,由于某种原因,内存没有返回到操作系统或可用内存池中。

    原因

    1.意外的全局变量

    JS 在处理未声明的变量时,对未声明的变量的引用会在全局对象内创建一个新变量。这些全局变量是无法进行垃圾回收的(除非将它们赋值为 null 或重新进行分配),所以对于存储大量数据的全局变量,确保在使用完之后,对其赋值为 null 或者重新分配。

    1.  
      function leak(){
    2.  
      leak="xxx";//leak成为一个全局变量,不会被回收
    3.  
      }

    2.被遗忘的定时器(Timers)或者回调函数(callback)

    1.  
      var someResouce=getData();
    2.  
      setInterval(function(){
    3.  
      var node=document.getElementById('Node');
    4.  
      if(node){
    5.  
      node.innerHTML=JSON.stringify(someResouce)
    6.  
      }
    7.  
      },1000)
    8.  
      // 如果 id 为 Node 的元素从 DOM 中移除, 该定时器仍会存在,
    9.  
      // 而且, 因为回调函数中包含对 someResource 的引用, 定时器外面的 someResource 也不会被释放。

    3.闭包函数

    1.  
      function bindEvent(){
    2.  
      var obj=document.createElement("XXX");
    3.  
      obj.οnclick=function(){
    4.  
      //Even if it's a empty function
    5.  
      }
    6.  
      }

     

    闭包可以维持函数内局部变量,使其得不到释放。 上例定义事件回调时,由于是函数内定义函数,并且内部函数--事件回调的引用外暴了,形成了闭包。解决之道,将事件处理函数定义在外部,解除闭包,或者在定义事件处理函数的外部函数中,删除对dom的引用。

    1.  
      //将事件处理函数定义在外部
    2.  
      function onclickHandler(){
    3.  
      //do something
    4.  
      }
    5.  
       
    6.  
      function bindEvent(){
    7.  
      var obj=document.createElement("XXX");
    8.  
      obj.οnclick=onclickHandler;
    9.  
      }
    10.  
       
    11.  
       
    12.  
      //在定义事件处理函数的外部函数中,删除对dom的引用
    13.  
      function bindEvent(){
    14.  
      var obj=document.createElement("XXX");
    15.  
      obj.οnclick=function(){
    16.  
      //Even if it's a empty function
    17.  
      }
    18.  
      obj=null;
    19.  
      }
     

    4.没有清理的DOM元素的引用

    1.  
      var elements={
    2.  
      button: document.getElementById("button"),
    3.  
      image: document.getElementById("image"),
    4.  
      text: document.getElementById("text")
    5.  
      };
    6.  
      function doStuff(){
    7.  
      image.src="http://some.url/image";
    8.  
      button.click():
    9.  
      console.log(text.innerHTML)
    10.  
      }
    11.  
      function removeButton(){
    12.  
      document.body.removeChild(document.getElementById('button'))
    13.  
      }

    5.子元素存在引起的内存泄露

    黄色是指直接被 js变量所引用,在内存里,红色是指间接被 js变量所引用,如上图,refB 被 refA 间接引用,导致即使 refB 变量被清空,也是不会被回收的。子元素 refB 由于 parentNode 的间接引用,只要它不被删除,它所有的父元素(图中红色部分)都不会被删除。

    在举个例子,假设我们在 JavaScript 代码中保留了对 table 特定单元格(<td>)的引用。有一天,我们决定从 DOM 中删除该 table,但仍保留着对该单元格的引用。直观地来看,可以假设 GC 将收集除了该单元格之外所有的内容。实际上,这是不会发生的,因为该单元格是该 table 的子节点,并且 children 保持着对它们 parents 的引用。也就是说,在 JavaScript 代码中对单元格的引用会导致整个表都保留在内存中的。

    6.IE7/8引用计数使用循环引用产生的问题

    这个问题主要是在于IE7/8的垃圾回收机制,使用的是引用计数法,当两个变量A和B相互引用时,即使应用程序中不再使用这两个变量,GC也不会将这两个变量回收。

    1.  
      function fn(){
    2.  
      var a={};
    3.  
      var b={};
    4.  
      a.pro=b;
    5.  
      b.pro=a;
    6.  
      }
    7.  
      fn();

    排查

    Google Chrome浏览器提供了非常强大的JS调试工具,Memory 视图  profiles 视图让你可以对 JavaScript 代码运行时的内存进行快照,并且可以比较这些内存快照。它还让你可以记录一段时间内的内存分配情况。在每一个结果视图中都可以展示不同类型的列表,但是对我们最有用的是 summary 列表和 comparison 列表。  summary 视图提供了不同类型的分配对象以及它们的合计大小:shallow size (一个特定类型的所有对象的总和)和 retained size (shallow size 加上保留此对象的其它对象的大小)。distance 显示了对象到达 GC 根(校者注:最初引用的那块内存,具体内容可自行搜索该术语)的最短距离。 comparison 视图提供了同样的信息但是允许对比不同的快照。这对于找到泄漏很有帮助。

    右边视图中列出了heap里的对象列表。

    • constructor:类名
    • Distance:对象到根的引用层级距离
    • Objects Count:该类的对象数
    • Shallow Size:对象所占内存(不包含内部引用的其他对象所占的内存)
    • Retained Size:对象所占的总内存(包含····················································)

    内存泄漏的排查

    将上图框框切换到comparison(对照)选项,该视图列出了当前视图与上一个视图的对象差异

    • New:新建了多少对象
    • Deleted:回收了多少对象
    • Delta:新建的对象个数减去回收的对象个数

    重点看closure(闭包),如果#Delta为正数,则表示创建了闭包函数,如果多个快照中都没有变负数,则表示没有销毁闭包

    转载于:https://www.cnblogs.com/ygunoil/p/10562270.html

    展开全文
  • 前文已经讲过了OleCtrls.pas是如何内存泄漏以及解决方案,但是我们发现该内存泄漏的问题,早已被TEmbeddedWB发现,TEmbeddedWB在Version 14.67.8版本的解决方案并不修改OleCtrls.pas文件,而是每次执行内存泄漏的...

    前文已经讲过了OleCtrls.pas是如何内存泄漏以及解决方案,但是我们发现该内存泄漏的问题,早已被TEmbeddedWB发现,TEmbeddedWB在Version 14.67.8版本的解决方案并不修改OleCtrls.pas文件,而是每次执行内存泄漏的地方,额外的写上一句_Release;使得引用计数无条件减少1,该方案有点绕路子,而且会与修正问题本质的方案(修改OleCtrls.pas)发生冲突,而且一旦Borland修正了OleCtrls.pas的问题,那么TembeddedWB也就无法正常使用了。更具有讽刺意义的是TEmbeddedWB并没有在所有地方都这样做,那么它也没有解决全部的内存泄漏。

    参看部分代码:

    procedure TEmbeddedWB.SetUserAgentInt;
    var
      Control: IOleControl;
    begin
      
    if FUserAgent <> FUserAgentInt then
      
    begin
        RestoreUserAgentReg;
        
    if DefaultInterface.QueryInterface(IOleControl, Control) = 0 then
          
    with (Application as IOleControl) do
          
    begin
            FUserAgentInt :
    = FUserAgent;
            Control.OnAmbientPropertyChange(DISPID_AMBIENT_USERAGENT);
            
    //_Release;
          
    end;
      
    end;
    end;

    于是已经修改OleCtrls.pas的用户将无法正常使用TEmbeddedWB Version 14.67.8 以及附近的版本,在TEmbeddedWB 早期版本例如:14.64是不存在被动修复方案的,所以已经修改OleCtrls.pas的用户可以正常使用TEmbeddedWB 14.64以及附近的版本。

    TEmbeddedWB Version 14.67.8我已经作了一个补丁,删除TEmbeddedWB 额外增加的所有_Release调用。这是一个SVN的补丁文件,请看:

     

    ContractedBlock.gifExpandedBlockStart.gifCode
    Index: EmbeddedWB.pas
    ===================================================================
    --- EmbeddedWB.pas    (版本 681)
    +++ EmbeddedWB.pas    (工作副本)
    @@ 
    -2583,7 +2583,7 @@
           begin
             FUserAgentInt :
    = FUserAgent;
             Control.OnAmbientPropertyChange(DISPID_AMBIENT_USERAGENT);
    -        _Release;
    +        //_Release;
           end;
       end;
     end;
    Index: EwbCore.pas
    ===================================================================
    --- EwbCore.pas    (版本 681)
    +++ EwbCore.pas    (工作副本)
    @@ 
    -1337,7 +1337,7 @@
         with (Application 
    as IOleControl) do
         begin
           OnAmbientPropertyChange(DISPID_AMBIENT_USERMODE);
    -      _Release;
    +      //_Release;
         end;
     end;
     
    @@ 
    -1374,7 +1374,7 @@
       with (Application 
    as IOleControl) do
       begin
         OnAmbientPropertyChange(DISPID_AMBIENT_DLCONTROL);
    -    _Release;
    +    //_Release;
       end;
     end;
     
    @@ 
    -1438,7 +1438,7 @@
       with (Application 
    as IOleControl) do
       begin
         OnAmbientPropertyChange(DISPID_AMBIENT_DLCONTROL);
    -    _Release;
    +    //_Release;
       end;
     end;
     
    Index: EWBTools.pas
    ===================================================================
    --- EWBTools.pas    (版本 681)
    +++ EWBTools.pas    (工作副本)
    @@ 
    -1003,7 +1003,7 @@
           ScreenImg.SaveToFile(FileName);
           Result :
    = True;
         
    finally
    -      ViewObject._Release;
    +      //ViewObject._Release;
         end;
       except
         Result :
    = False;
    @@ 
    -3049,7 +3049,7 @@
         
    try
           Result :
    = CmdTarget.Exec(PtrGuid, Value1, Value2, vaIn, vaOut);
         
    finally
    -      CmdTarget._Release;
    +      //CmdTarget._Release;
         end;
       except
       end;
    Index: IEDownload.pas
    ===================================================================
    --- IEDownload.pas    (版本 681)
    +++ IEDownload.pas    (工作副本)
    @@ 
    -6,7 +6,7 @@
     
    //                     Freeware Component                                 *
     
    //                       for Delphi by                                    *
     
    //                      Eran Bodankin                                     *
    -//                   and Per Linds?Larsen                                *
    +//                   and Per Linds?Larsen                                *
     
    //                                                                        *
     
    //                                                                        *
     
    //  Updated versions:                                                     *
    @@ -895,7 +895,7 @@
         Result :
    = S_OK;
       FBSCBTimer.Enabled :
    = True; {Timeout timer}
       FTimedOut :
    = False;
    -  Self._Release;
    +  //Self._Release;
     end;
     
     function TBSCB.OnResponse(dwResponseCode: DWORD; szResponseHeaders,
    @@ 
    -1493,9 +1493,9 @@
         
    else if (Assigned(FSender.FOnConnect)) then
           FSender.FOnConnect(Self, HR, Registering_new_moniker 
    +
             ResponseCodeToStr(HR));
    -    m_pPrevBSCB._Release;
    +    //m_pPrevBSCB._Release;
         m_pPrevBSCB := nil;
    -    FBindCtx._Release;
    +    //FBindCtx._Release;
         FBindCtx := nil;
         Dec(FSender.FRefCount);
       end;
    @@ 
    -1512,7 +1512,7 @@
         FSender.FOnStopBinding(Self, HRESULT, szError);
     
       Result :
    = HRESULT;
    -  Binding._Release; {Release the binding we called on StartBinding}
    +  //Binding._Release; {Release the binding we called on StartBinding}
     
       FSender.FState :
    = sStopped;
       
    if Assigned(FSender.FOnStateChange) then
    Index: MenuContext.pas
    ===================================================================
    --- MenuContext.pas    (版本 681)
    +++ MenuContext.pas    (工作副本)
    @@ 
    -370,7 +370,7 @@
                   end;
           
    finally
             ShellMalloc.Free(FolderID);
    -        ShellMalloc._Release;
    +        //ShellMalloc._Release;
           end;
         end;
       
    finally
    @@ 
    -416,7 +416,7 @@
         FreeMem(ItemPIDLs);
       end;
       ShellMalloc.Free(FolderID);
    -  ShellMalloc._Release;
    +  //ShellMalloc._Release;
     end;
     
     function NextPIDL(PIDL: PItemIDList): PItemIDList;
    Index: RichEditBrowser.pas
    ===================================================================
    --- RichEditBrowser.pas    (版本 681)
    +++ RichEditBrowser.pas    (工作副本)
    @@ 
    -828,7 +828,7 @@
     begin
       
    if IUnknown(Obj) <> nil then
       begin
    -    IUnknown(Obj)._Release;
    +    //IUnknown(Obj)._Release;
         IUnknown(Obj) := nil;
       end;
     end;

    转载于:https://www.cnblogs.com/manors/archive/2009/05/25/1488917.html

    展开全文
  • 二、怎么发生内存泄漏? 三、发生后定位处理? 四、总结 一、何为内存泄露? 何为内存泄漏?又是怎么发生的呢?通过对Linux系统内存工作原理的了解,我们知道: 普通进程通过页表将内核提供的虚拟内存映射...

    目录

    一、何为内存泄露?

    二、怎么发生内存泄漏?

    三、发生后定位处理?

    四、总结


     

    一、何为内存泄露?

    何为内存泄漏?又是怎么发生的呢?通过对Linux系统内存工作原理的了解,我们知道:

    • 普通进程通过页表将内核提供的虚拟内存映射到物理内存。

    • 当进程通过 malloc() 申请虚拟内存后,系统并不会立即为其分配物理内存,而是在首次访问时,才通过缺页异常陷入内核中分配内存。

    • 协调 CPU 与磁盘间的性能差异,提升系统的 I/O 性能,Linux 还会使用 Cache 和 Buffer ,分别把文件和磁盘读写的数据缓存到内存中。

    也正如我们所了解的,对应用程序来说,动态内存的分配和回收是既核心又复杂的一个逻辑功能模块。管理内存的过程中,也很容易发生各种各样的“事故”,比如:

    • 没正确回收分配后的内存,导致了泄漏。

    • 访问的是已分配内存边界外的地址,导致程序异常退出,等等。

    如下百度百科解释:

    内存泄漏(Memory Leak)是指程序中已动态分配的堆内存由于某种原因程序未释放或无法释放,造成系统内存的浪费,导致程序运行速度减慢甚至系统崩溃等严重后果。

    内存泄露是指:用动态存储分配函数动态开辟的空间,在使用完毕后未释放,结果导致一直占据该内存单元。直到程序结束。(其实说白了就是该内存空间使用完毕之后未回收)即所谓内存泄漏。

     

    二、怎么发生内存泄漏?

    进程的内存空间时,用户空间内存包括多个不同的内存段,比如只读段、数据段、堆、栈以及文件映射段等。这些内存段正是应用程序使用内存的基本方式。举个例子:

    (1)程序中定义了一个局部变量,比如一个整数数组 int data[64] ,就定义了一个可以存储 64 个整数的内存段。

    由于这是一个局部变量,它会从内存空间的栈中分配内存。

    栈内存由系统自动分配和管理。一旦程序运行超出了这个局部变量的作用域,栈内存就会被系统自动回收,所以不会产生内存泄漏的问题。

    (2)假如不知道数据大小,用到标准库函数 malloc() ,在程序中动态分配内存。这时候,系统就会从内存空间的堆中分配内存。

    堆内存由应用程序自己来分配和管理。除非程序退出,这些堆内存并不会被系统自动释放,而是需要应用程序明确调用库函数 free() 来释放它们。如果应用程序没有正确释放堆内存,就会造成内存泄漏。

    问题:栈真的不会内存泄漏嘛?具体在什么场景下会有?

    其他内存段是否也会导致内存泄漏呢?

    • 只读段,包括程序的代码和常量,由于是只读的,不会再去分配新的内存,所以也不会产生内存泄漏。

    • 数据段,包括全局变量和静态变量,这些变量在定义时就已经确定了大小,所以也不会产生内存泄漏

    • 内存映射段,包括动态链接库和共享内存,其中共享内存由程序动态分配和管理。所以,如果程序在分配后忘了回收,就会导致跟堆内存类似的泄漏问题。

     

    内存泄漏的危害非常大,这些忘记释放的内存,不仅应用程序自己不能访问,系统也不能把它们再次分配给其他应用。内存泄漏不断累积,甚至会耗尽系统内存。

    在发现内存紧张时,系统就会通过一系列机制来回收内存,比如下面这三种方式:

    回收缓存,比如使用 LRU(Least Recently Used)算法,回收最近使用最少的内存页面;

    回收不常访问的内存,把不常用的内存通过交换分区直接写到磁盘中;

    杀死进程,内存紧张时系统还会通过 OOM(Out of Memory),直接杀掉占用大量内存的进程。

    虽然,系统最终可以通过 OOM (Out of Memory)机制杀死进程,但进程在 OOM 前,可能已经引发了一连串的反应,导致严重的性能问题。比如,

    • 其他需要内存的进程,可能无法分配新的内存;

    • 内存不足,又会触发系统的缓存回收以及 SWAP 机制

    • 从而进一步导致 I/O 的性能问题等等。

    三、发生后定位处理?

    内存泄漏的危害这么大,那我们应该怎么检测这种问题呢?特别是,如果你已经发现了内存泄漏,该如何定位和处理呢。

    (1)怎么检查内存情况,判断有没有泄漏发生呢?

    vmstat 工具(man vmstat获取帮助)

    top 虽然能观察系统和进程的内存占用情况;对于内存泄漏问题,我们更应该关注内存使用的变化趋势。

    # 每隔3秒输出一组数据$ vmstat 3procs -----------memory---------- ---swap-- -----io---- -system-- ------cpu-----r  b   swpd   free   buff  cache   si   so    bi    bo   in   cs us sy id wa stprocs -----------memory---------- ---swap-- -----io---- -system-- ------cpu-----r  b   swpd   free   buff  cache   si   so    bi    bo   in   cs us sy id wa st0  0      0 6601824  97620 1098784    0    0     0     0   62  322  0  0 100  0  00  0      0 6601700  97620 1098788    0    0     0     0   57  251  0  0 100  0  00  0      0 6601320  97620 1098788    0    0     0     3   52  306  0  0 100  0  00  0      0 6601452  97628 1098788    0    0     0    27   63  326  0  0 100  0  02  0      0 6601328  97628 1098788    0    0     0    44   52  299  0  0 100  0  00  0      0 6601080  97628 1098792    0    0     0     0   56  285  0  0 100  0  0

    从输出中你可以看到,内存的 free 列在不停的变化,并且是下降趋势;而 buffer 和 cache 基本保持不变。

    未使用内存在逐渐减小,而 buffer 和 cache 基本不变,这说明,系统中使用的内存一直在升高。但这并不能说明有内存泄漏,因为应用程序运行中需要的内存也可能会增大。比如说,程序中如果用了一个动态增长的数组来缓存计算结果,占用内存自然会增长。

    (2)那怎么确定是不是内存泄漏?有没有简单方法找出让内存增长的进程,并定位增长内存用在哪儿呢?

    memleak工具

    top 或 ps 来观察进程的内存使用情况,然后找出内存使用一直增长的进程。最后再通过 pmap 查看进程的内存分布。要判断内存的变化情况,还需要你写一个脚本,来处理 top 或者 ps 的输出。

    可以使用一个专门用来检测内存泄漏的工具memleak。memleak是bcc 软件包中的一个工具,安装bcc-tools执行 /usr/share/bcc/tools/memleak 就可以运行它

    memleak 可以跟踪系统或指定进程的内存分配、释放请求,然后定期输出一个未释放内存和相应调用栈的汇总情况(默认 5 秒)
    # -a 表示显示每个内存分配请求的大小以及地址# -p 指定案例应用的PID号$ /usr/share/bcc/tools/memleak -a -p pid
    

    四、总结

    应用程序可以访问的用户内存空间,由只读段、数据段、堆、栈以及文件映射段等组成。其中,堆内存和文件映射段,需要应用程序来动态管理内存段,所以我们必须小心处理。不仅要会用标准库函数 malloc() 来动态分配内存,还要记得在用完内存后,调用库函数 free() 来释放它们。

    malloc() 和 free() 通常并不是成对出现,需要在每个异常处理路径和成功路径上都释放内存 。在多线程程序中,一个线程中分配的内存,可能会在另一个线程中访问和释放。更复杂的是,在第三方的库函数中,隐式分配的内存可能需要应用程序显式释放。

    所以,为了避免内存泄漏,最重要的一点就是养成良好的编程习惯,比如分配内存后,一定要先写好内存释放的代码,再去开发其他逻辑。还是那句话,有借有还,才能高效运转,再借不难。

    当然,如果已经完成了开发任务,可以用 memleak 工具,检查应用程序的运行中,内存是否泄漏。如果发现了内存泄漏情况,再根据 memleak 输出的应用程序调用栈,定位内存的分配位置,从而释放不再访问的内存。

     

     

     

    展开全文
  • 如何检测和处理内存泄漏如何查找引起内存泄漏的原因一般有两个步骤:第一是安排有经验的编程人员对代码进行走查和分析,找出内存泄漏发生的位置;第二是使用专门的内存泄漏测试工具进行测试. 第一个步骤:在代码走查的...
    四. 如何检测和处理内存泄漏

    如何查找引起内存泄漏的原因一般有两个步骤:第一是安排有经验的编程人员对代码进行走查和分析,找出内存泄漏发生的位置;第二是使用专门的内存泄漏测试工具进行测试.

    第一个步骤:在代码走查的工作中,可以安排对系统业务和开发语言工具比较熟悉的开发人员对应用的代码进行了交叉走查,尽量找出代码中存在的数据库连接声明和结果集未关闭、代码冗余等故障代码.

    第二个步骤:就是检测Java的内存泄漏.在这里我们通常使用一些工具来检查Java程序的内存泄漏问题.市场上已有几种专业检查Java内存泄漏的工具,它们的基本工作原理大同小异,都是通过监测Java程序运行时,所有对象的申请、释放等动作,将内存管理的所有信息进行统计、分析、可视化.开发人员将根据这些信息判断程序是否有内存泄漏问题.这些工具包括Optimizeit Profiler,JProbe Profiler,JinSight , Rational 公司的Purify等.

    4.1检测内存泄漏的存在
    这里我们将简单介绍我们在使用Optimizeit检查的过程.通常在知道发生内存泄漏之后,第一步是要弄清楚泄漏了什么数据和哪个类的对象引起了泄漏.

    一般说来,一个正常的系统在其运行稳定后其内存的占用量是基本稳定的,不应该是无限制的增长的.同样,对任何一个类的对象的使用个数也有一个相对稳定的上限,不应该是持续增长的.根据这样的基本假设,我们持续地观察系统运行时使用的内存的大小和各实例的个数,如果内存的大小持续地增长,则说明系统存在内存泄漏,如果特定类的实例对象个数随时间而增长(就是所谓的“增长率”),则说明这个类的实例可能存在泄漏情况.

    另一方面通常发生内存泄漏的第一个迹象是:在应用程序中出现了OutOfMemoryError.在这种情况下,需要使用一些开销较低的工具来监控和查找内存泄漏.虽然OutOfMemoryError也有可能应用程序确实正在使用这么多的内存;对于这种情况则可以增加JVM可用的堆的数量,或者对应用程序进行某种更改,使它使用较少的内存.

    但是,在许多情况下,OutOfMemoryError都是内存泄漏的信号.一种查明方法是不间断地监控GC的活动,确定内存使用量是否随着时间增加.如果确实如此,就可能发生了内存泄漏.

    4.2处理内存泄漏的方法
    一旦知道确实发生了内存泄漏,就需要更专业的工具来查明为什么会发生泄漏.JVM自己是不会告诉您的.这些专业工具从JVM获得内存系统信息的方法基本上有两种:JVMTI和字节码技术(byte code instrumentation).
    Java虚拟机工具接口(Java Virtual Machine Tools Interface,JVMTI)及其前身Java虚拟机监视程序接口(Java Virtual Machine Profiling Interface,JVMPI)是外部工具与JVM通信并从JVM收集信息的标准化接口.字节码技术是指使用探测器处理字节码以获得工具所需的信息的技术.

    Optimizeit是Borland公司的产品,主要用于协助对软件系统进行代码优化和故障诊断,其中的Optimizeit Profiler主要用于内存泄漏的分析.Profiler的堆视图就是用来观察系统运行使用的内存大小和各个类的实例分配的个数的.

    首先,Profiler会进行趋势分析,找出是哪个类的对象在泄漏.系统运行长时间后可以得到四个内存快照.对这四个内存快照进行综合分析,如果每一次快照的内存使用都比上一次有增长,可以认定系统存在内存泄漏,找出在四个快照中实例个数都保持增长的类,这些类可以初步被认定为存在泄漏.通过数据收集和初步分析,可以得出初步结论:系统是否存在内存泄漏和哪些对象存在泄漏(被泄漏).

    接下来,看看有哪些其他的类与泄漏的类的对象相关联.前面已经谈到
    Java中的内存泄漏就是无用的对象保持,简单地说就是因为编码的错误导致了一条本来不应该存在的引用链的存在(从而导致了被引用的对象无法释放),因此内存泄漏分析的任务就是找出这条多余的引用链,并找到其形成的原因.查看对象分配到哪里是很有用的.同时只知道它们如何与其他对象相关联(即哪些对象引用了它们)是不够的,关于它们在何处创建的信息也很有用.
      转自:
    雨后池塘(www.YuHou.net)
    最后,进一步研究单个对象,看看它们是如何互相关联的.借助于Profiler工具,应用程序中的代码可以在分配时进行动态添加,以创建堆栈跟踪.也有可以对系统中所有对象分配进行动态的堆栈跟踪.这些堆栈跟踪可以在工具中进行累积和分析.对每个被泄漏的实例对象,必然存在一条从某个牵引对象出发到达该对象的引用链.处于堆栈空间的牵引对象在被从栈中弹出后就失去其牵引的能力,变为非牵引对象.因此,在长时间的运行后,被泄露的对象基本上都是被作为类的静态变量的牵引对象牵引.

    总而言之,
    Java虽然有自动回收管理内存的功能,但内存泄漏也是不容忽视,它往往是破坏系统稳定性的重要因素.
    展开全文
  • 随着现在的编程语言功能越来越成熟、复杂,内存管理也容易被大家忽略。本文将会讨论JavaScript中的内存泄漏以及如何处理,方便大家在使用JavaScript编码时,更好的应对内存泄漏带来的问题。
  • 对于PHP-FPM多进程的模式,想要避免内存泄漏问题很简单,就是要让PHP-CGI在处理一定数量进程后退出即可。否则PHP程序或第三方模块(如Imagemagick扩展)导致的内存泄漏问题会导致内存耗尽或不足。php-fpm.conf中有相关...
  • 我们还将提供一些有关如何处理JavaScript中的内存泄漏的技巧,在SessionStack中遵循这些技巧,既能确保SessionStack 不会导致内存泄漏,也不会增加我们集成的Web应用程序的内存消耗。 概述 像 C 这样的编程语言,...
  • 处理内存泄漏c++

    2014-08-11 15:00:28
    首先就是如何查找内存泄漏问题,经过学长指点,使用vld2.4(官网下载) 头文件中加入#include ,然后可以直接运行,运行完毕之后,窗口会显示出错的地方。 可参考下面网址的文章: ...
  • 3. 如何处理非静态内部类内存泄漏问题 一、不同生命周期导致的内存泄漏 前面有分析了内存泄漏的原因,本该被回收的对象被占用,得不到回收便会内存泄漏。总归到底的原因还是对象引用在类之间传递,它们的生命周期...
  • JavaScript 是如何工作的:内存管理 + 如何处理四种常见的内存泄漏 原文 - How JavaScript works: memory management + how to handle 4 common memory leaks 原文作者 - Alexander Zlatkov 原文地址 - blog....
  • 我们需要一些工具进行检测,并发现内存泄漏问题,不然很容易发生down机问题。 编写java程序最为方便的地方就是我们不需要管理内存的分配和释放,一切由jvm来进行处理,当java对象不再被应用时,等到堆内存不够...
  • 为什么要进行内存优化?在android中,对内存的优化是一个app很重要的一个... 一张图来描述微信各个版本所占用的系统内存: 常见程序程序所占用的内存: 如果内存无法妥善处理好,容易出现如下问题:内存泄漏、内...
  • 而JavaScript在创建对象(对象、字符串等)时会为它们分配内存,不再使用时会“自动”释放内存,这个过程称为垃圾收集。这种看似“自动”释放资源的的特性是造成混乱的根源,因为这给JavaScript(和其他高级语言)开发...
  • JavaScript是如何工作的:内存管理以及如何处理四种常见的内存泄漏 原文:How JavaScript works: memory management + how to handle 4 common memory leaks 译者:neal1991 welcome to star my articles-...
  • 本文将会讨论JavaScript中的内存泄漏以及如何处理,方便大家在使用JavaScript编码时,更好的应对内存泄漏带来的问题。 概述 像C语言这样的编程语言,具有简单的内存管理功能函数,例如malloc( )和free( )。开发人员...
  • 本篇译文,删减了原文中一些无关紧要的内容,可以让大家花更少的阅读时间。 原文地址:... 这篇文章将讨论日常编程中另一个复杂且容易被忽视的问题 — 内存管理。其中还提供...
  • 我们还将提供一些有关如何处理JavaScript中的内存泄漏的技巧,在SessionStack中遵循这些技巧,既能确保SessionStack 不会导致内存泄漏,也不会增加我们集成的Web应用程序的内存消耗。 概述 像 C 这样的编程语言,...

空空如也

空空如也

1 2 3 4 5 ... 20
收藏数 657
精华内容 262
关键字:

如何处理内存泄漏