内存溢出 订阅
内存溢出(Out Of Memory,简称OOM)是指应用系统中存在无法回收的内存或使用的内存过多,最终使得程序运行要用到的内存大于能提供的最大内存。此时程序就运行不了,系统会提示内存溢出,有时候会自动关闭软件,重启电脑或者软件后释放掉一部分内存又可以正常运行该软件,而由系统配置、数据流、用户代码等原因而导致的内存溢出错误,即使用户重新执行任务依然无法避免 [1]  。 展开全文
内存溢出(Out Of Memory,简称OOM)是指应用系统中存在无法回收的内存或使用的内存过多,最终使得程序运行要用到的内存大于能提供的最大内存。此时程序就运行不了,系统会提示内存溢出,有时候会自动关闭软件,重启电脑或者软件后释放掉一部分内存又可以正常运行该软件,而由系统配置、数据流、用户代码等原因而导致的内存溢出错误,即使用户重新执行任务依然无法避免 [1]  。
信息
领    域
计算机科学
原    因
程序实际运行需要内存的大小不够
简    称
OOM
影    响
使程序终止运行
中文名
内存溢出
解决方法
关闭软件、重启电脑或者软件、增加内存
外文名
out of memory
内存溢出简介
内存溢出已经是软件开发历史上存在了近40年的“老大难”问题,像在“红色代码”病毒事件中表现的那样,它已经成为黑客攻击企业网络的“罪魁祸首”。 如在一个域中输入的数据超过了它的要求就会引发数据溢出问题,多余的数据就可以作为指令在计算机上运行。据有关安全小组称,操作系统中超过50%的安全漏洞都是由内存溢出引起的,其中大多数与微软的技术有关。内存溢出错误是大数据处理平台的常见错误,例如,国际知名的程序开发者问答网站 stackoverflow 上关于“Hadoop out of memory”的问题超过10000个,在Spark邮件列表上有10%的问题是关于“out of memory”。 内存溢出错误会导致处理数据的任务失败,甚至会引发平台崩溃等严重后果。对于内存溢出大部分的处理方法是重新执行任务,然而, 对于由系统配置、数据流、用户代码等原因而导致的内存溢出错误,即使用户重新执行任务依然无法避免 [1]  。内存溢出通俗理解就是内存不够,是指运行程序时要求的内存,超出了系统所能分配的范围,从而导致发生内存溢出。一般在运行大型软件时,所需的内存远远超出了主机内安装的内存所承受大小时就会发生这种情况。当出现内存溢出这种情况,系统一般会提示相关信息,有时候会自动关闭软件甚至会造成设备卡死等现象,重启电脑或者软件后释放掉一部分内存又可以正常运行该软件或游戏一段时间。 [2] 
收起全文
精华内容
参与话题
问答
  • (精华)2020年8月31日 .NET 内存溢出

    万次阅读 2020-08-31 00:02:58
    内存溢出的几种情况 一:事件驱动 原因事件对象没有被释放,或者一直引用着 class TestClassHasEvent { public delegate void TestEventHandler(object sender, EventArgs e); public event TestEventHandler ...

    内存溢出的几种情况

    一:事件驱动

    原因事件对象没有被释放,或者一直引用着

    class TestClassHasEvent     
     {     
         public delegate void TestEventHandler(object sender, EventArgs e);     
         public event TestEventHandler YourEvent;     
         protected void OnYourEvent(EventArgs e)     
         {     
             if (YourEvent != null) YourEvent(this, e);     
         }     
     }    
    //public TestListener(TestClassHasEvent inject)
    //{
    //    SystemEvents.DisplaySettingsChanged += new EventHandler(SystemEvents_DisplaySettingsChanged);
    //}
    
    //void SystemEvents_DisplaySettingsChanged(object sender, EventArgs e)
    //{
    
    //}
    class TestListener     
     {    
         byte[] m_ExtraMemory = new byte[1000000];    
          
         private TestClassHasEvent _inject;    
          
         public TestListener(TestClassHasEvent inject)    
         {    
             _inject = inject;    
             _inject.YourEvent += new TestClassHasEvent.TestEventHandler(_inject_YourEvent);    
         }    
             
         void _inject_YourEvent(object sender, EventArgs e)    
         {    
                 
         }    
     }    
          
     class Program    
     {    
         static void DisplayMemory()    
         {    
             Console.WriteLine("Total memory: {0:###,###,###,##0} bytes", GC.GetTotalMemory(true));    
         }    
          
         static void Main()    
         {    
             DisplayMemory();    
             Console.WriteLine();    
             for (int i = 0; i < 5; i++)    
             {    
                 Console.WriteLine("--- New Listener #{0} ---", i + 1);    
          
                 var listener = new TestListener(new TestClassHasEvent());    
                listener = null; //可有可无    
                     
                 GC.Collect();    
                 GC.WaitForPendingFinalizers();    
                 GC.Collect();    
                 DisplayMemory();    
                     
             }    
             Console.Read();    
         }    
     }      
    

    解决方案

    class TestListener : IDisposable     
    {     
        byte[] m_ExtraMemory = new byte[1000000];    
          
        private TestClassHasEvent _inject;     
          
        public TestListener(TestClassHasEvent inject)    
        {    
            SystemEvents.DisplaySettingsChanged += new EventHandler(SystemEvents_DisplaySettingsChanged);    
        }    
         
        void SystemEvents_DisplaySettingsChanged(object sender, EventArgs e)    
        {    
              
        }    
           
        #region IDisposable Members    
         
        public void Dispose()    
         {    
            SystemEvents.DisplaySettingsChanged -= new EventHandler(SystemEvents_DisplaySettingsChanged);    
        }    
         
        #endregion    
    }    
         
    class Program    
    {    
        static void DisplayMemory()    
        {    
             Console.WriteLine("Total memory: {0:###,###,###,##0} bytes", GC.GetTotalMemory(true));    
        }    
         
        static void Main()    
        {    
            DisplayMemory();    
            Console.WriteLine();    
            for (int i = 0; i < 5; i++)    
            {    
                 Console.WriteLine("--- New Listener #{0} ---", i + 1);    
                    
                using (var listener = new TestListener(new TestClassHasEvent()))    
                {    
                     //do something    
                 }    
                GC.Collect();    
                 GC.WaitForPendingFinalizers();    
                GC.Collect();    
                DisplayMemory();    
                    
            }    
            Console.Read();    
        }    
    }  
    

    上面两个例子一个内存泄露,一个没有内存泄露,我想你应该知道原因了,根本区别在于后者有个SystemEvents.DisplaySettingsChanged事件,这个事件是静态Static事件,所以绑定到这个事件上的对象都不会被释放

    // Type: Microsoft.Win32.SystemEvents  
    // Assembly: System, Version=4.0.0.0, Culture=neutral, PublicKeyToken=b77a5c561934e089  
    // Assembly location: C:\Program Files\Reference Assemblies\Microsoft\Framework\.NETFramework\v4.0\Profile\Client\System.dll  
       
     using System;  
     using System.ComponentModel;  
        
     namespace Microsoft.Win32  
     {  
         public sealed class SystemEvents  
         {  
             public static IntPtr CreateTimer(int interval);  
             public static void InvokeOnEventsThread(Delegate method);  
             public static void KillTimer(IntPtr timerId);  
             public static event EventHandler DisplaySettingsChanging;  
             public static event EventHandler DisplaySettingsChanged;  
             public static event EventHandler EventsThreadShutdown;  
             public static event EventHandler InstalledFontsChanged;  
         
             [EditorBrowsable(EditorBrowsableState.Never)]  
             [Obsolete("This event has been deprecated. http://go.microsoft.com/fwlink/?linkid=14202")]  
             [Browsable(false)]  
             public static event EventHandler LowMemory;  
        
             public static event EventHandler PaletteChanged;  
             public static event PowerModeChangedEventHandler PowerModeChanged;  
             public static event SessionEndedEventHandler SessionEnded;  
             public static event SessionEndingEventHandler SessionEnding;  
             public static event SessionSwitchEventHandler SessionSwitch;  
             public static event EventHandler TimeChanged;  
             public static event TimerElapsedEventHandler TimerElapsed;  
             public static event UserPreferenceChangedEventHandler UserPreferenceChanged;  
             public static event UserPreferenceChangingEventHandler UserPreferenceChanging;  
           }  
    }  
    

    注意Static,注意Singleton 这种static的东西生命周期很长,永远不会被GC回收,一旦被他给引用上了,那就不可能释放了。上面的例子就是SystemEvents.DisplaySettingsChanged += new EventHandler(SystemEvents_DisplaySettingsChanged);那就意味着这个类被SystemEvents.DisplaySettingsChanged 引用了,通过它的函数。另外一个要注意的是Singleton单例模式实现的类,他们也是static的生命周期很长,要注意引用链,你的类是否被它引用上,如果在它的引用链上,就内存泄露了。

    另外还有注意程序运行期间不会释放的对象的事件

    还有一种情况,既不是你的对象被static对象而不能释放,也不是Singleton,而是你的对象被一个永远不释放的对象引用着,这个对象或许不是static的。这种类型很多,比如你的界面有个MainForm,嘿嘿,这个MainForm永远不会关闭和释放的,被它引用了那就不会释放了。看个例子:

    MainForm里面有个public event,MainForm里面打开Form2,然后关闭,看看Form2能不能释放:

    public partial class MainForm : Form     
    {     
        public event PropertyChangedEventHandler PropertyChanged;     
          
       protected virtual void OnPropertyChanged(string propertyName)     
       {     
            PropertyChangedEventHandler handler = PropertyChanged;     
          
            if (handler != null)    
                handler(this, new PropertyChangedEventArgs(propertyName));    
        }    
         
        public MainForm()    
        {    
            InitializeComponent();    
        }    
         
        private void button1_Click(object sender, EventArgs e)    
        {    
            Form2 frm = new Form2();   
         
            this.PropertyChanged += frm.frm_PropertyChanged;     
            //MainForm referenced form2, because main form is not released, therefore form2 will not released.    
         
            DialogResult d = frm.ShowDialog();    
                
            GC.Collect();    
            ShowTotalMemory();    
         
        }    
         
            
        
        private void ShowTotalMemory()    
        {    
            this.listBox1.Items.Add(string.Format("Memory: {0:###,###,###,##0} bytes", GC.GetTotalMemory(true)));    
        }    
    }  
    

    Form2里面有个函数:

    public partial class Form2 : Form     
     {     
         public Form2()     
         {     
             InitializeComponent();     
         }     
         public void frm_PropertyChanged(object sender, PropertyChangedEventArgs e)     
         {     
          
         }    
     }  
    

    所以这种情况下,你的Event handler没有手动注销,那就肯定内存泄露了。

    二:非托管资源

    public partial class MemoryLeak
    {
         
        public static void Demo2()
        {
    
            while (true)
            {
                var x = File.OpenRead($"c:\\audio.log");
            }
        }
    }
    

    三:线程等待

    public partial class MemoryLeak
    {
        /// <summary>
        /// https://docs.microsoft.com/zh-cn/previous-versions/dotnet/articles/ms973858(v=msdn.10)?redirectedfrom=MSDN
        /// </summary>
    
        public static void Demo3()
        {
    
            {
                while (true)
                { 
                    Console.ReadLine();
                    Thread t = new Thread(new ThreadStart(ThreadProc));
                    t.Start();
                }
            }
        }
    
        static void ThreadProc()
        { 
            Thread.CurrentThread.Join();
        }
    }
    

    四:字符串

    本地程序集用const,跨程序集用readnoly

    public partial class MemoryLeak
        { 
    
            public static void Demo4()
            {
                List<string> asd = new List<string>();
                while (true)
                {
                    ///String它存放的并不是普通的堆
                    ///.NET有一个叫做内存驻地的东西---->字符串池--->字符串驻留池
                    ///你的这些String会存放起来并不会"完全"遵照GC走
                    asd.Add(Guid.NewGuid().ToString());
                    if (asd.Count > 10000)
                    {
                        asd.Clear();
                        Console.WriteLine("asdasdasdasd" + 1);
                        Console.WriteLine("Error info");
                        Console.WriteLine("Error  info");
                        Console.WriteLine("error");
                        Console.WriteLine("erorr");
                    }
                }
            }
        }
    
    展开全文
  • 内存溢出

    2019-04-25 10:36:02
    1.什么是内存溢出 内存溢出是指应用系统中存在无法回收的内存或使用的内存过多,最终使得程序运行要用到的内存大于虚拟机能提供的最大内存。 2.引起内存溢出的原因  1.内存中加载的数据量过于庞大,如一次从数据库...

    1.什么是内存溢出
    内存溢出是指应用系统中存在无法回收的内存或使用的内存过多,最终使得程序运行要用到的内存大于虚拟机能提供的最大内存。
    2.引起内存溢出的原因
      1.内存中加载的数据量过于庞大,如一次从数据库取出过多数据;
      2.集合类中有对对象的引用,使用完后未清空,使得JVM不能回收;
      3.代码中存在死循环或循环产生过多重复的对象实体;
      4.使用的第三方软件中的BUG;
      5.启动参数内存值设定的过小;
    3.内存溢出解决方案
    第一步,修改JVM启动参数,直接增加内存。(-Xms,-Xmx参数一定不要忘记加。)
    第二步,检查错误日志,查看“OutOfMemory”错误前是否有其它异常或错误。
    第三步,对代码进行走查和分析,找出可能发生内存溢出的位置。
    4.出现内存溢出如何排查
    1.检查对数据库查询中,是否有一次获得全部数据的查询。一般来说,如果一次取十万条记录到内存,就可能引起内存溢出。这个问题比较隐蔽,在上线前,数据库中数据较少,不容易出问题,上线后,数据库中数据多了,一次查询就有可能引起内存溢出。因此对于数据库查询尽量采用分页的方式查询。
    2.检查代码中是否有死循环或递归调用。?
    3.检查是否有大循环重复产生新对象实体。?
    4.检查List、MAP等集合对象是否有使用完后,未清除的问题。List、MAP等集合对象会始终存有对对象的引用,使得这些对象不能被GC回收。
    5.内存溢出分类
    主要是堆堆溢出:
    a.内存泄露:是指对象实例在新建和使用完毕后,仍然被引用,没能被垃圾回收释放,一直累计只到没有剩余的内存可用;
    b.内存溢出:当我们新建一个实例对象时,实例对象所需占用的内存空间大于堆的可用空间.

    展开全文
  • 内存溢出自动导出参数: //发生溢出时dump出来 -XX:+HeapDumpOnOutOfMemoryError //dump的路径 ./为项目启动根路径 -XX:HeapDumpPath=./ 内存溢出手动导出参数:jmap命令使用 jdk安装后会自带一些小工具,jmap...

    内存溢出自动导出参数:

    //发生溢出时dump出来 
    -XX:+HeapDumpOnOutOfMemoryError
    //dump的路径 ./为项目启动根路径 
    -XX:HeapDumpPath=./

    内存溢出手动导出参数:jmap命令使用

    jdk安装后会自带一些小工具,jmap命令(Java Memory Map)是其中之一。主要用于打印指定Java进程(或核心文件、远程调试服务器)的共享对象内存映射或堆内存细节。

    jmap命令可以获得运行中的jvm的堆的快照,从而可以离线分析堆,以检查内存泄漏,检查一些严重影响性能的大对象的创建,检查系统中什么对象最多,各种对象所占内存的大小等等。可以使用jmap生成Heap Dump。

    关于jamp的命令jdk的官方上很详细,不赘述了。

    注意:jmap的dump 将内存使用的详细情况输出到文件

    jmap -dump:live,format=b,file=heap.bin pid //说明:内存信息dump到a.log文件中

    这个命令执行,JVM会将整个heap的信息dump写入到一个文件,heap如果比较大的话,就会导致这个过程比较耗时,并且执行的过程中为了保证dump的信息是可靠的,所以会暂停应用

    通常做法是:

    1)首先配置JVM启动参数,让JVM在遇到OutOfMemoryError时自动生成Dump文件

    -XX:+HeapDumpOnOutOfMemoryError -XX:HeapDumpPath=/path
    

    2)然后使用命令

    jmap  -dump:format=b,file=/path/heap.bin 进程ID  
    
    如果只dump heap中的存活对象,则加上选项-live。 
    

     3)然后使用MAT分析工具,如jhat命令,eclipse的mat插件

    最后在eclipse中安装MAT插件(http://www.eclipse.org/mat/),
    然后在eclipse中,file---->open,打开这个文件heap.bin,利用现成的OOM工具进行分析。
    具体操作方法:
    首先输入网址http://www.eclipse.org/mat/previousReleases.php,然后查看你自己的Eclipse版本,
    我的是Indigo的,
    所以点击链接“Previous Releases”,选择Indigo版本的URLhttp://download.eclipse.org/mat/1.1.0/update-site/ 

     用jhat命令可以参看 jhat -port 5000 heapDump 在浏览器中访问:http://localhost:5000/ 查看详细信息

     

    展开全文
  • android 图片内存溢出

    2017-08-09 02:36:00
    **在界面显示多个图片的时候(10多张图片,每张500Kb左右),就会出现内存溢出的日志,但是应用不会崩溃,只会导致图片不显示,只显示占位图或者加重错误的图片。 这种情况只在一种设备上出现(厂家定制的设备),...
  • 基础面试3:内存溢出 vs 内存泄漏

    万次阅读 2020-11-16 11:38:45
    内存溢出 out of memory:程序运行过程中申请的内存 > 系统能够提供的内存,导致无法申请到足够的内存;比如申请了一个integer,但给它存了long才能存下的数,那就是内存溢出。 举个例子 需求> 供应,当欲望>...

    一、基本概念

    在这里插入图片描述

    在这里插入图片描述

    1,内存溢出 out of memory

    程序运行过程中申请的内存 > 系统能够提供的内存,导致无法申请到足够的内存 ;比如申请了一个integer,但给它存了long才能存下的数,那就是内存溢出。

    举个例子 需求> 供应,当欲望>工资 时候,就会发生 OOM;
    

    1,内存泄露 memory leak

    内存泄漏指程序运行过程中分配内存给临时变量,用完之后却没有被GC回收,始终占用着内存,既不能被使用也不能分配给其他程序,于是就发生了内存泄漏。比方说栈,栈满时再做进栈必定产生空间溢出,叫上溢,栈空时再做退栈也产生空间溢出,称为下溢。就是分配的内存不足以放下数据项序列,称为内存溢出.

    举个例子 油罐里的资源(石油)被人偷了部分,偷走的石油无法被控制,导致“泄露”;  
    

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

    二、内存溢出OOM常见情况

    内存溢出有以下几种常见的情况:

    1、java.lang.OutOfMemoryError: PermGen space (持久带溢出)

    • 我们知道jvm通过持久带实现了java虚拟机规范中的方法区,而运行时常量池就是保存在方法区中的,因此发生这种溢出可能是运行时常量池溢出,或是由于程序中使用了大量的jar或class,使得方法区中保存的class对象没有被及时回收或者class信息占用的内存超过了配置的大小。

    2、java.lang.OutOfMemoryError: Java heap space (堆溢出)

    • 发生这种溢出的原因一般是创建的对象太多,在进行垃圾回收之前对象数量达到了最大堆的容量限制。

    解决这个区域异常的方法一般是通过内存映像分析工具对Dump出来的堆转储快照进行分析,看到底是内存溢出还是内存泄漏。如果是内存泄漏,可进一步通过工具查看泄漏对象到GC Roots的引用链,定位出泄漏代码的位置,修改程序或算法;如果不存在泄漏,就是说内存中的对象确实都还必须存活,那就应该检查虚拟机的堆参数-Xmx(最大堆大小)和-Xms(初始堆大小),与机器物理内存对比看是否可以调大。

    3、虚拟机栈和本地方法栈溢出

    • 如果线程请求的栈深度大于虚拟机所允许的最大深度,将抛出StackOverflowError。

    如果虚拟机在扩展栈时无法申请到足够的内存空间,则抛出OutOfMemoryError。

    三、内存泄漏常见情况

    1,为什么会发生内存泄露

    来先看看下面的例子,为什么会发生内存泄漏。下面这个例子中,A对象引用B对象,A对象的生命周期(t1-t4)比B对象的生命周期(t2-t3)长的多。当B对象没有被应用程序使用之后,A对象仍然在引用着B对象。这样,垃圾回收器就没办法将B对象从内存中移除,从而导致内存问题,因为如果A引用更多这样的对象,那将有更多的未被引用对象存在,并消耗内存空间。

    B对象也可能会持有许多其他的对象,那这些对象同样也不会被垃圾回收器回收。所有这些没在使用的对象将持续的消耗之前分配的内存空间。
    在这里插入图片描述

    内存管理的目的就是让我们在开发中怎么有效的避免我们的应用出现内存泄漏的问题。

    2,Java 内存分配策略

    Java 程序运行时的内存分配策略有三种,分别是静态分配,栈式分配,和堆式分配,对应的,三种存储策略使用的内存空间主要分别是静态存储区(也称方法区)、栈区堆区

    3,内存泄漏分类

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

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

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

    4,常见内存泄漏case

    1. 静态集合类引起的内存泄漏:

    像HashMap、Vector等的使用最容易出现内存泄露,这些静态变量的生命周期和应用程序一致,他们所引用的所有的对象Object也不能被释放,从而造成内存泄漏,因为他们也将一直被Vector等引用着。

            Vector<Object> v=new Vector<Object>(100);
            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。

    1. 修改HashSet中对象的参数值,且参数是计算哈希值的字段

    当一个对象被存储到HashSet集合中以后,修改了这个对象中那些参与计算哈希值的字段后,这个对象的哈希值与最初存储在集合中的就不同了,这种情况下,用contains方法在集合中检索对象是找不到的,这将会导致无法从HashSet中删除当前对象,造成内存泄漏,举例如下:

    public static void main(String[] args){
    
        Set<Person> set = new HashSet<Person>();
        Person p1 = new Person("张三","1",25);
        Person p2 = new Person("李四","2",26);
        Person p3 = new Person("王五","3",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);
        }
    }
    
    1. 监听器
      在java 编程中,我们都需要和监听器打交道,通常一个应用当中会用到很多监听器,我们会调用一个控件的诸如addXXXListener()等方法来增加监听器,但往往在释放对象的时候却没有记住去删除这些监听器,从而增加了内存泄漏的机会。

    2. 各种连接

      比如数据库连接(dataSourse.getConnection()),网络连接(socket)和io连接,除非其显式的调用了其close() 方法将其连接关闭,否则是不会自动被GC 回收的。对于Resultset 和Statement 对象可以不进行显式回收,但Connection 一定要显式回收,因为Connection 在任何时候都无法自动回收,而Connection一旦回收,Resultset 和Statement 对象就会立即为NULL。但是如果使用连接池,情况就不一样了,除了要显式地关闭连接,还必须显式地关闭Resultset Statement 对象(关闭其中一个,另外一个也会关闭),否则就会造成大量的Statement 对象无法释放,从而引起内存泄漏。这种情况下一般都会在try里面去连接,在finally里面释放连接。

    3. 单例模式

      如果单例对象持有外部对象的引用,那么这个外部对象将不能被jvm正常回收,导致内存泄露。

      不正确使用单例模式是引起内存泄露的一个常见问题,单例对象在被初始化后将在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是个比较复杂的对象或者集合类型会发生什么情况。

    4,避免内存泄漏建议

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

    2. 避免在循环中创建对象。

    3. 使用字符串处理时避免使用String,应使用StringBuffer。

    4. 尽量少使用静态变量,因为静态变量存放在永久代,基本不参与垃圾回收。

    参考链接:

    • https://blog.csdn.net/qq_35642036/article/details/82809780
    • https://www.cnblogs.com/xiaoxi/p/7354857.html
    • https://blog.csdn.net/qq_36576738/article/details/55203035
    展开全文
  • spring junit 内存溢出

    2014-11-11 09:31:50
    测试类如下: @RunWith(SpringJUnit4ClassRunner.class) ...项目比较大,spring文件分的很多,相互之间又有引用,我索性把全部文件加载进来,是不是因为加载的文件多,而导致的内存溢出?要如何解决呢?
  • 一直报内存溢出,内存已设置成最大1500M, 还是溢出,在线等高手帮忙解决 获取个连接需要那么多内存吗? 还是我哪写的不对啊 错误信息: Exception in thread "main" java.lang.OutOfMemoryError: Java heap ...
  • jvm 内存溢出-直接内存溢出 DirectMemory 容量可通过 -XX:MaxDirectMemorySize 指定,如果不指定,则默认与 Java 堆最大值( -Xmx 指定)一样,下面程序利用 DirectByteBuffe 模拟直接内存溢出的情况 import java....
  • Java与C++之间有- -堵由内存动态分配和垃圾收集技术所围成的“高墙”,墙外面的人想进去,墙里面的人却想出来。 2.1 概述 对于从事C、C++程序开发的开发人员来说,在内存管理领域,他们既是拥有最高权力的“皇帝”...
  • 内存溢出与内存泄漏

    千次阅读 2016-03-17 15:27:21
    内存泄漏(memory leak)指由于疏忽或错误造成程序未能释放已经不再使用的内存的情况,是应用程序分配某段内存后,由于程序设计错误而导致JVM失去了对该段内存的控制,因而造成了内存的浪费。一般内存泄漏是指堆内存...
  • java内存溢出之永久代内存溢出

    千次阅读 2018-02-03 15:29:25
    在实际开发中,我们经常会遇到oom,即所谓的内存溢出情况,但是不能是所有的内存溢出都一概而论,我们需要搞清楚具体内存的溢出原因和分类然后对症下药。这里和大家一起学习一下内存溢出中的永久代内存溢出。 ...
  • kettle内存溢出

    千次阅读 2013-12-19 20:11:19
    ETL工具kettle,在老版设计后,使用新版时,居然发生了内存溢出的错误: 出现: java heap  或者 OutOfMemory等字样  这是kettle分配的内存不足。 在kettle的运行路径中,用文本编辑器打开Spoon.bat,找到: ...
  • 内存溢出和内存泄漏的区别

    万次阅读 多人点赞 2011-07-19 16:38:24
    内存溢出,是指程序在申请内存时,没有足够的内存空间供其使用,出现out of memory;比如申请了一个integer,但给它存了long才能存下的数,那就是内存溢出。内存泄露,是指程序在申请内存后,无法释放已申请的内存...
  • eclipse内存溢出解决办法查看内存 编辑该知识 1 查看内存: workspace/.metadata/.plugins/org.eclipse.core.runtime/.settings/org.eclipse.ui.prefs,在里面加上SHOW_MEMORY_MONITOR=true,重启eclipse,就...
  • 出处1:http://www.iteye.com写java程序时大家一定对一下两条异常并不陌生: java.lang.OutOfMemoryError: Java heap space java.lang.OutOfMemoryError: Perm... 好的编码实践可能会大大降低内存溢出的产生。 ...
  • 把tomcat安装到windows的服务里启动,连访问tomcat的主页都会报OutOfMemoryError: PermGen space内存溢出错误,但小弟已经到注册表里加大了tomcat的运行内存。如下图 ![JvmMs和JvmMx都设置了1024,在Options的后面...
  • Java内存溢出与栈溢出

    千次阅读 2017-05-12 11:01:17
    一、背景知识 1、JVM体系结构 ...JVM运行时内存 = 共享内存区 + 线程内存区 3-1、共享内存区 共享内存区 = 持久带 + 堆 持久带 = 方法区 + 其他 堆 = Old Space + You
  • 另外有一个情况,就是如果我连续运行这四个拆分程序,那么到第三个的时候才会提示内存不足,如果我重启apache单独运行他们,那么每一个都不会导致内存溢出。我在程序循环中和循环外几乎把所有定义过的变量都unset()...
  • 这样在内存溢出时显示进程已经杀死,但是执行启动命令时会报地址已经被占用,实际进程确实杀死了,新开一个命令终端执行catalina.sh是可以启动的,但是在原终端因为端口被占用无法启动,谁可以给我分析一下,我想...
  • package com.www.lyz; import java.util.ArrayList; import java.util.List; public class a5 { public static int c = 0; public static int d = 0;... public static List list = new Array
  • 深入理解Java虚拟机-Java内存区域与内存溢出异常

    万次阅读 多人点赞 2020-01-03 21:42:24
    Java与C++之间有一堵由内存动态分配和垃圾收集技术所围成的"高墙",墙外面的人想进去,墙里面的人却想出来。 文章目录概述运行时数据区域程序计数器(线程私有)Java虚拟机栈(线程私有)局部变量表操作数栈动态链接...
  • Tomcat溢出、Java内存溢出

    千次阅读 2014-11-10 10:19:52
    Java内存溢出详解   一、常见的Java内存溢出有以下三种:   1. java.lang.OutOfMemoryError: Java heap space ----JVM Heap(堆)溢出 JVM在启动的时候会自动设置JVM Heap的值,其初始空间(即-Xms)是物理...
  • 在 本机上用eclipse导出一百多万的数据导出,没有问题,但是部署在应用服务器上就会内存溢出,而且我把本机的tomcat也拷贝过去了。其它一个功能,比这数据还多几W,只不过少写出了几个字段,也能正常导出。 int ...
  • 代码报错位置(字符串可以看到json串,但是执行报内存溢出): ![图片说明](https://img-ask.csdn.net/upload/201606/15/1465961492_415406.jpg) 我是在本地tomcat8下面跑的,按照网上所说,我修改了catalina...
  • Java程序中Jsoup解析大量html内存溢出,资源没有回收,内存一直增长 [code="java"] 最近要改别人写的一个解析html入库的程序,原本没有抽取正文的代码,就自己找了一个放了进去,是根据Jsoup解析写的,运行之后...
  • 内存溢出 out of memory,是指程序在申请内存时,没有足够的内存空间供其使用,出现out of memory;比如申请了一个integer,但给它存了long才能存下的数,那就是内存溢出。 内存泄露 memory leak,是指程序在申请...
  • jmeter内存溢出解决方法(OutOfMemoryError:内存溢出

    万次阅读 热门讨论 2018-06-24 15:55:25
    如果出现了内存溢出的问题,可以通过调整JVM内存相关的参数进行优化。    具体过程如下: 1、找到jmeter.bat文件,也就是我们启动jmeter的脚本: 2、打开jmeter.bat文件,对以下这些配置项进行编辑: ...

空空如也

1 2 3 4 5 ... 20
收藏数 35,351
精华内容 14,140
关键字:

内存溢出