什么是内存泄漏和内存溢出(内存溢出和内存泄漏的不同之处)
如果有更好的建议或者想看更多关于技术大全及相关资讯,可以多多关注茶馆百科网。

一、基本概念
内存溢出:简单地说,内存溢出是指程序运行过程中申请的内存大于系统提供的内存。导致申请的内存不足,内存溢出。
内存泄漏:内存泄漏是指在程序运行期间将内存分配给临时变量,但使用后内存不被GC收集,始终占用内存,无法使用或分配给其他程序,因此发生内存泄漏。
内存溢出意味着程序在申请内存时没有足够的内存空间可以使用。
内存泄漏是指程序申请内存后,无法释放所申请的内存空间。内存泄漏的损害可以忽略不计,但是内存泄漏积累的后果是严重的。无论存多少内存,迟早都要用完。
内存泄漏最终会导致内存不足!
内存泄漏是指由于无用对象(不再使用的对象)占用内存或无用对象的内存未及时释放而造成的内存空间浪费。内存泄漏有时可能是轻微和微妙的,因此开发人员不知道它的存在,但它也可能是严重的,并提示您内存不足。
二、内存溢出的常见情况
以下几种情况会导致内存溢出:
1, Java。朗。OutOfMemoryError: PermGen空间(持久性溢出)
我们知道jvm通过持久性磁带实现java虚拟机规范的方法区,并且运行时常量池存储在方法区中,因此这种溢出可能是运行时常量池溢出的结果,或者是因为程序中使用了大量的jar或类。存储在方法区的类对象没有及时回收,或者类信息占用的内存超过了配置的大小。
2, Java。朗。OutOfMemoryError: Java堆空间(堆溢出)
这种溢出通常是因为创建了太多的对象,并且在垃圾收集之前达到了最大堆容量限制。
解决这个问题的方法是使用内存映像分析工具分析Dump快照,查看是否存在内存溢出或内存泄漏。如果是内存泄漏,可以通过工具进一步检查泄漏对象对GC Roots的引用链,定位泄漏代码的位置,并修改程序或算法。如果没有泄漏,这意味着内存中的对象确实必须仍然是活动的,那么您应该检查虚拟机的堆参数-Xmx(最大堆大小)和-Xms(初始堆大小),看看它们是否可以根据机器的物理内存进行扩展。
3.虚拟机堆栈和本地方法堆栈溢出
如果线程请求的堆栈深度大于虚拟机允许的最大深度,则引发StackOverflowError。
如果虚拟机在扩展堆栈时无法获得足够的内存空间,则抛出OutOfMemoryError。
[
三、内存泄漏
]内存泄漏的根本原因是长寿命对象持有对短寿命对象的引用。虽然不再需要短寿命对象,但它不能被回收,因为长寿命对象保存着它的引用。
按照发生的方式分类,内存泄漏可以分为四类:
1. 频繁的内存泄漏。有内存泄漏的代码会被执行多次,每次执行都会导致内存泄漏。
2. 意外内存泄漏。具有内存泄漏的代码只能在某些情况或操作下发生。复发性和发作性是相对的。在某些情况下,偶尔可能会复发。因此,测试环境和测试方法对于检测内存泄漏非常重要。
3.一次性内存泄漏。有内存泄漏的代码只执行一次,或者由于算法中的缺陷,总是在一块且只有一块内存中存在泄漏。例如,内存是在类的构造函数中分配的,而不是在析构函数中释放的,因此内存泄漏只能发生一次。
4. 隐式内存泄漏。程序在整个运行过程中分配内存,但直到运行结束才释放内存。严格地说,没有内存泄漏,因为程序最终会释放所有请求的内存。但是对于运行数天、数周甚至数月的服务器程序,不及时释放内存可能导致系统最终耗尽内存。因此,我们称这种类型的内存泄漏为隐式内存泄漏。
从用户使用程序的角度来看,内存泄漏本身不会造成任何危害,作为普通用户,并不会感觉到内存泄漏的存在。真正的危险是内存泄漏的累积,最终可能消耗系统的所有内存。从这个角度来看,一次性内存泄漏是无害的,因为它不会累积,而隐式内存泄漏非常有害,因为它比反复出现或偶尔出现的内存泄漏更难检测。
1. 由静态集合类引起的内存泄漏:
静态变量如HashMap、Vector等最容易发生内存泄漏。这些变量与应用程序具有相同的生命周期,它们引用的所有对象都不能被释放,这会导致内存泄漏,因为它们总是被Vector等引用。
VectorObject v=new VectorObject(100);For (int I=1;i100;在本例中,我们循环遍历Object并将应用的对象放入Vector中。如果我们只释放引用本身(0=null), Vector仍然引用对象,因此它不能被GC回收。因此,如果一个对象被添加到Vector中,它也必须从Vector中移除。最简单的方法是将Vector设置为null。
2. 修改HashSet中对象的参数值,这些参数就是计算hash值的字段
在将对象存储在HashSet集合中之后,通过修改对象中涉及计算哈希值的字段,该对象的哈希值与最初存储在集合中的哈希值不同。在这种情况下,无法找到使用contains方法检索集合中的对象。这将导致当前对象无法从HashSet中删除,从而导致内存泄漏,如下例所示:
public static void main(String[] args)}侦听器
在java编程中,我们都需要处理侦听器,经常在一个应用程序中使用多个侦听器,我们会调用addXXXListener()等控件方法来添加侦听器,但往往在对象释放时不记得删除侦听器,增加了内存泄漏的机会。
4. 各种连接
例如,数据库连接(dataSourse.getConnection())、网络连接(socket)和io连接不会被GC自动回收,除非它们通过调用close()方法显式关闭。Resultset和Statement对象可以不显式回收,但Connection必须显式回收,因为Connection在任何时候都不能自动回收,并且一旦Connection被回收,Resultset和Statement对象立即为NULL。但是,如果使用连接池,情况就不同了。除了显式关闭连接外,还必须显式关闭Resultset Statement对象(如果关闭一个,另一个也会关闭),否则会导致大量Statement对象无法释放,导致内存泄漏。在这种情况下,连接通常在try中被删除,在finally中被释放。
5. 单例模式
如果单例持有对外部对象的引用,则jvm将无法正确回收外部对象,从而导致内存泄漏。
单例模式的不当使用是导致内存泄漏的常见问题。在初始化之后,单例对象将在JVM的整个生命周期中存在(作为静态变量)。如果单例包含对外部对象的引用,则jvm将无法正确地回收外部对象,从而导致内存泄漏。
c
A类.}//类B public static B getInstance() public void setA(A A) //getter…Class B public static B getInstance() public void seta (a) //getter…显然B使用了单例模式。它持有对A类对象的引用,并且这个A类对象不能被回收。想象一下,如果A是一个复杂的对象或集合类型会发生什么。
一些避免内存泄漏的建议:
1. 尽快释放对无用对象的引用。
2. 避免在循环中创建对象。
3.使用字符串时避免使用字符串,而是使用StringBuffer。
4、尽量少使用静态变量,因为静态变量是永久存储生成的,基本不参与垃圾回收。
本文主要介绍了关于什么是内存泄漏和内存溢出(内存溢出和内存泄漏的不同之处)的相关养殖或种植技术,栏目还介绍了该行业生产经营方式及经营管理,关注发展动向,注重系统性、科学性、实用性和先进性,内容全面新颖、重点突出、通俗易懂,全面给您讲解技术怎么管理的要点,是您致富的点金石。
以上文章来自互联网,不代表本人立场,如需删除,请注明该网址:http://23.234.50.4:8411/article/1559665.html