首页 > 系统相关 >内存泄漏和内存溢出

内存泄漏和内存溢出

时间:2023-09-18 21:45:28浏览次数:34  
标签:泄漏 数据库 查询 内存 memory 溢出

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

内存溢出就是你要求分配的内存超出了系统能给你的,系统不能满足需求,于是产生溢出。

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

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

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

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

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

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

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

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

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

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

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

1.内存中加载的数据量过于庞大,如一次从数据库取出过多数据;

2.集合类中有对对象的引用,使用完后未清空,使得JVM不能回收;

3.代码中存在死循环或循环产生过多重复的对象实体;

4.使用的第三方软件中的BUG;

5.启动参数内存值设定的过小

内存溢出的解决方案:

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

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

第三步,对代码进行走查和分析,找出可能发生内存溢出的位置。

重点排查以下几点:

1.检查对数据库查询中,是否有一次获得全部数据的查询。一般来说,如果一次取十万条记录到内存,就可能引起内存溢出。这个问题比较隐蔽,在上线前,数据库中数据较少,不容易出问题,上线后,数据库中数据多了,一次查询就有可能引起内存溢出。因此对于数据库查询尽量采用分页的方式查询。

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

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

4.检查对数据库查询中,是否有一次获得全部数据的查询。一般来说,如果一次取十万条记录到内存,就可能引起内存溢出。这个问题比较隐蔽,在上线前,数据库中数据较少,不容易出问题,上线后,数据库中数据多了,一次查询就有可能引起内存溢出。因此对于数据库查询尽量采用分页的方式查询。

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

第四步,使用内存查看工具动态查看内存使用情况

标签:泄漏,数据库,查询,内存,memory,溢出
From: https://www.cnblogs.com/zcj-gh/p/17713139.html

相关文章

  • idea设置项目启动的JVM运行内存大小
    idea设置项目启动的JVM运行内存大小场景在开发当中,idea默认服务启动要占用1G内存。其实每个项目本地开发和调试的时候,根本不需要1G内存,200M左右足以如果在微服务体系下,那效果更明显,相同的内存可以启动更多的服务刚好本人的电脑只有8G,公司的微服务项目启动后,电脑风扇疯狂的转动......
  • 动态内存分配(callco,realloc,笔试题目)2
    相比于malloc加了有一个自动初始化的功能intmain(){ int*p=(int*)calloc(10,sizeof(int));//创建之后就默认数据初始化为0 if(p==NULL) { printf("%s\n",strerror(errno)); } else { inti=0; for(i=0;i<10;i++) { *(p+i)=i; } for(i......
  • 从内核世界透视 mmap 内存映射的本质(原理篇)
    本文基于内核5.4版本源码讨论之前有不少读者给笔者留言,希望笔者写一篇文章介绍下mmap内存映射相关的知识体系,之所以迟迟没有动笔,是因为mmap这个系统调用看上去简单,实际上并不简单,可以说是非常复杂的一个系统调用。如果想要给大家把mmap背后的技术本质,正确地,清晰地还原......
  • C/C++中结构体占用内存大小的计算方法
    两个值:对齐系数:一般为8个字节。#pragmapack(8)设置对齐系数为8。有效对齐值:假设结构体中最长的类型的长度为len,则有效对齐值=min(len,对齐系数)。计算规则:计算存放的位置:第一个成员放在位置0,后面的成员A存放的时候,会先计算size=min(A大小,有效对齐值),A只放在size的整数倍......
  • JAVA 线上故障排查完整套路,从 CPU、磁盘、内存、网络、GC 一条龙!
    https://mp.weixin.qq.com/s/zaoypK8nn1egoKFFLKxNLQ   (给Java日知录加星标,提高Java技能)线上故障主要会包括cpu、磁盘、内存以及网络问题,而大多数故障可能会包含不止一个层面的问题,所以进行排查时候尽量四个方面依次排查一遍。同时例如jstack、jmap等工具也是不囿于一个......
  • C#中的高级主题:内存管理、性能优化和安全性
    简介:欢迎来到C#语言入门指南的第十三篇博客!在之前的博客中,我们已经学习了C#的基础和一些高级编程概念。今天,我们将深入研究C#中的高级主题,包括内存管理、性能优化和安全性,以帮助您构建更出色的应用程序。让我们开始吧!1.内存管理:了解C#中的内存管理是非常重要的,它可以帮助您避免......
  • CPU/内存/磁盘/网络/redis/MQ测试工具合集
    闲余时间为大家整理了CPU性能测试、内存带宽测试、内存延迟测试、磁盘IOPS测试、网络测试、数据库测试、Kafka/rabbitMQ性能测试工具合集,后续也会对工具进行简单使用说明。序号工具名称监控策略及内容1UnixBench-5.1.4CPU性能测试2stream内......
  • 记一次 .NET 某电力系统 内存暴涨分析
    一:背景1.讲故事前些天有位朋友找到我,说他生产上的程序有内存暴涨情况,让我帮忙看下怎么回事,最简单粗暴的方法就是让朋友在内存暴涨的时候抓一个dump下来,看一看大概就知道咋回事了。二:Windbg分析1.到底是谁吃了内存这个问题说的再多也不为过,一定要看清楚这个程序是如何个性......
  • 手把手教你模拟 JVM 内存溢出场景
    Java全能学习+面试指南:https://javaxiaobear.cn今天我们主要自己模拟一个JVM内存溢出的场景。在模拟JVM内存溢出之前我们先来看下这样的几个问题。老年代溢出为什么那么可怕?元空间也有溢出?怎么优化?如何配置栈大小?避免栈溢出?进程突然死掉,没有留下任何信息时如何进......
  • 动态内存分配(malloc,free)1
    使用动态内存开辟函数,可以创捷长度可变的数组大小,这样可以减少空间的浪费。在创建可变长度的数组时,其实在C99标准下,是可以直接创建的,例如linux下gcc编译器可以通过编译命令gcctest.c-std=c99,来实现。在vs下是不支持的,所以需要通过内存开辟函数来进行创建。在开辟空间的时候,有可能......