内存溢出是什么 内存溢出的原因和解决方法
内存溢出(Out Of Memory,简称OOM)是指应用系统中存在无法回收的内存或使用的内存过多,最终使得程序运行要用到的内存大于能提供的最大内存。此时程序就运行不了,系统会提示内存溢出,有时候会自动关闭软件,重启电脑或者软件后释放掉一部分内存又可以正常运行该软件,而由系统配置、数据流、用户代码等原因而导致的内存溢出错误,即使用户重新执行任务依然无法避免。
简介
内存溢出已经是软件开发历史上存在了近 40 年的“老大难”问题,像在“红色代码”病毒事件中表现的那样,它已经成为黑客攻击企业网络的“罪魁祸首”。 如在一个域中输入的数据超过了它的要求就会引发数据溢出问题,多余的数据就可以作为指令在计算机上运行。据有关安全小组称,操作系统中超过 50%的安全漏洞都是由内存溢出引起的,其中大多数与微软的技术有关。内存溢出错误是大数据处理平台的常见错误,例如,国际知名的程序开发者问答网站 stackoverflow 上关于“Hadoop out of memory”的问题超过 10000 个,在 Spark 邮件列表上有 10%的问题是关于“out of memory”。 内存溢出错误会导致处理数据的任务失败,甚至会引发平台崩溃等严重后果。对于内存溢出大部分的处理方法是重新执行任务,然而, 对于由系统配置、数据流、用户代码等原因而导致的内存溢出错误,即使用户重新执行任务依然无法避免。
内存溢出通俗理解就是内存不够,是指运行程序时要求的内存,超出了系统所能分配的范围,从而导致发生内存溢出。一般在运行大型软件时,所需的内存远远超出了主机内安装的内存所承受大小时就会发生这种情况。
当出现内存溢出这种情况,系统一般会提示相关信息,有时候会自动关闭软件甚至会造成设备卡死等现象,重启电脑或者软件后释放掉一部分内存又可以正常运行该软件或游戏一段时间。
常见现象
以 Android 开发为例,在开发过程中经常遇到 Android 内存溢出的意外情况的发生。
以下是国内外总结造成内存溢出的几点现象。
1.大量位图的加载
Bitmap 代表一张位图文件,扩展名是.bmp 或者.dip,它是非压缩格式,其显示效果较好,但缺点就是需要占用大量的存储空间。它是 windows 标准格式图形文件,由点组成,每一个点代表一个像素。每个点可以由多种色彩表示,包括 2、4、8、16、24 和 32 位色彩。色彩越高,显示效果越好,但所占用的字节数也就越大。计算一张 Bitmap 所占内存大小主要由 3 个因数有关,即图片宽度,图片长度,单位像素所占用的字节数。大小=图像长度*图片宽度*单位像素占用的字节数。有时候我们需要从网络上获取大量的图片并且展现在 view 中,但是如果图片较大,一次性加载大量 Bitmap,那么程序可用内存会瞬间增长,引起 OOM。
2.位图对象没有及时释放
当程序中需要操作 Bitmap 对象的时候,当它不在被使用的时候,可以调用 Bitmap.recycle()方法回收此对象的像素所占用的内存,如果对 Bitmap 没有及时释放,在程序长期运行过程中,就很有可能造成 OOM 意外情况的发生。
3.查询数据库没有关闭游标
程序中经常会进行查询数据库的操作,但是经常会有使用完毕 Cursor 后没有关闭的情况。如果我们的查询结果集比较小,对内存的消耗不容易被发现,只有在常时间大量操作的情况下才会复现内存问题,这样就会给以后的测试和问题排查带来困难和风险。
4.构造 Adapter 时,没有使用缓存的 convertView
以构造 ListView 的 BaseAdapter 为例,在 BaseAdapter 中提高了方法: publicView getView(int position, View convertView, ViewGroup parent)来向 ListView 提供每一个 item 所需要的 view 对象。初始时 ListView 会从 BaseAdapter 中根据当前的屏幕布局实例化一定数量的 view 对象,同时 ListView 会将这些 view 对象缓存起来。当向上滚动 ListView 时,原先位于最上面的 list item 的 view 对象会被回收,然后被用来构造新出现的最下面的 listitem.这个构造过程就是由 getView()方法完成的,getView()的第二个形参 View convertVicw 就是被缓存起来的 listitem 的 view 对象(初始化时缓存中没有 view 对象则 convertView 是 null)。如果我们不去使用 convertView,而是每次都在 getView()中重新实例化一个 View 对象的话,即浪费资源也浪费时间,也会使得内存占用越来越大。
原因
造成这种现象的原因通常有两种:
第一种是由于长期保持某些资源的引用,垃圾回收器无法回收它,从而使该资源不能够及时释放,也称为内存泄露;
另外一种是当需要保存多个耗用内存过大或当加载单个超大的对象时,该对象的大小超过了当前剩余的可用内存空间。
以 Android 程序为例:
1.由强引用造成的内存溢出
若所有的引用都是强引用,则大量内存会被占用,最终导致内存溢出。
解决方法:使用弱引用或软引用,软引用的对象在内存不足时可被 GC 回收,弱引用的对象在垃圾回收时可被回收。
2.由大量图片显示导致的内存溢出
为解决由大量图片显示造成的内存溢出,可以使用 BitmapFactory.Options 类,在返回参数时,只返回 Bitmap 的尺寸大小,而不将其加载到内存中,可有效减少内存溢出。同时在加载完后调用 system. gc()通知系统及时回收。
3.从数据库中取出大量数据造成的内存溢出
检查在数据库查询中,是否有一次获得全部数据的查询。一般而言,如果一次取十万条记录到内存,就可能引起内存溢出。该问题比较隐蔽,在上线前,数据库中数据较少,通常运行正常,上线后,数据库中数据增多,一次查询即有可能引起内存溢出。因此,对于数据库查询,尽量采用分页的方式查询。
4.代码中存在死循环或循环产生过多重复对象实体造成的内存溢出
出现这种情况,只能通过查看日志找出产生该问题的原因,检查代码中是否有死循环、递归调用,或大循环重复产生的新对象实体。
解决方法
内存溢出虽然很棘手,但也有相应的解决办法,可以按照从易到难,一步步的解决。以 Java 程序为例:
第一步,就是修改 JVM 启动参数,直接增加内存。这一点看上去似乎很简单,但很容易被忽略。JVM 默认可以使用的内存为 64M,Tomcat 默认可以使用的内存为 128MB,对于稍复杂一点的系统就会不够用。在某项目中,就因为启动参数使用的默认值,经常报“Out Of Memory”错误。因此,-Xms,-Xmx 参数一定不要忘记加。
第二步,检查错误日志,查看“Out Of Memory”错误前是否有其它异常或错误。在一个项目中,使用两个数据库连接,其中专用于发送短信的数据库连接使用 DBCP 连接池管理,用户为不将短信发出,有意将数据库连接用户名改错,使得日志中有许多数据库连接异常的日志,一段时间后,就出现“Out Of Memory”错误。经分析,这是由于 DBCP 连接池 BUG 引起的,数据库连接不上后,没有将连接释放,最终使得 DBCP 报“Out Of Memory”错误。经过修改正确数据库连接参数后,就没有再出现内存溢出的错误。
查看日志对于分析内存溢出是非常重要的,通过仔细查看日志,分析内存溢出前做过哪些操作,可以大致定位有问题的模块。
第三步,安排有经验的编程人员对代码进行走查和分析,找出可能发生内存溢出的位置。重点排查以下几点:
检查代码中是否有死循环或递归调用。
检查是否有大循环重复产生新对象实体。
检查对数据库查询中,是否有一次获得全部数据的查询。一般来说,如果一次取十万条记录到内存,就可能引起内存溢出。这个问题比较隐蔽,在上线前,数据库中数据较少,不容易出问题,上线后,数据库中数据多了,一次查询就有可能引起内存溢出。因此对于数据库查询尽量采用分页的方式查询。
检查 List、MAP 等集合对象是否有使用完后,未清除的问题。List、MAP 等集合对象会始终存有对对象的引用,使得这些对象不能被 GC 回收。
第四步,使用内存查看工具动态查看内存使用情况。某个项目上线后,每次系统启动两天后,就会出现内存溢出的错误。这种情况一般是代码中出现了缓慢的内存泄漏,用上面三个步骤解决不了,这就需要使用内存查看工具了。
内存查看工具有许多,比较有名的有:Optimizeit Profiler、JProbeProfiler、JinSight 和 Java1.5 的 Jconsole 等。它们的基本工作原理大同小异,都是监测 Java 程序运行时所有对象的申请、释放等动作,将内存管理的所有信息进行统计、分析、可视化。开发人员可以根据这些信息判断程序是否有内存泄漏问题。一般来说,一个正常的系统在其启动完成后其内存的占用量是基本稳定的,而不应该是无限制的增长的。持续地观察系统运行时使用的内存的大小,可以看到在内存使用监控窗口中是基本规则的锯齿形的图线,如果内存的大小持续地增长,则说明系统存在内存泄漏问题。通过间隔一段时间取一次内存快照,然后对内存快照中对象的使用与引用等信息进行比对与分析,可以找出是哪个类的对象在泄漏。
通过以上四个步骤的分析与处理,基本能处理内存溢出的问题。当然,在这些过程中也需要相当的经验与敏感度,需要在实际的开发与调试过程中不断积累。
避免内存溢出
避免内存溢出的常用方法众所周知,以 Android 开发为例,每个 Android 应用程序在运行时都有一定的内存限制,限制大小一般为 16MB 或 24MB(视平台而定)。当应用程序在实际运行过程中没有做到合理、有效利用内存空间,超过该限制大小就会内次溢出。
下面是列举了国内外在 Android 应用程序开发过程中应对内存溢出而经常采用的方法。
相关概念
内存泄露
内存泄露是造成内存溢出的其中一个原因,但是内存泄露不一定会造成内存溢出。简单来说,内存溢出就是占用内存太大,超过了系统可以承受的范围;而内存泄露则是由于对程序运行分配的对象回收不及时甚至于脆没有被回收,久而久之,则在系统分配的堆空间里面产生了很多无用的引用。
这种情况下,系统配置容量再多的内存空间都有可能发生内存溢出。当 Android 中 Dalivk 启动 GarbageCollection(GC)机制进行垃圾回收的时候,GC 会选择一些它了解还存活的对象作为内存遍历的根节点(GC Roots),比方说 thread stack 中的变量, JNI 中的全局变量,zygote 中的对象(class loader 加载)等,然后开始对 heap 进行遍历。到最后,部分没有直接或者间接引用到 GC Roots 的就是需要回收的垃圾,会被 GC 回收掉。GC 只能回收那么没有被引用的对象,如果一直引用,当遍历的时候,系统会默认为该对象仍然处于使用过程中,GC 无法回收供其他再次分配使用,但实际上这些被引用的对象对当前应用程序来说,是没有任何意义的,使得实际上可用的内存空间逐渐缩小。
以发生的方式进行分类,内存泄露可以具体分为如下几类:
(1) 偶发性内存泄露对造成内存泄露的代码只是在某些特定的环境或者操作过程下才会发生。一般情况下不会发生这种现象。
(2)常发性内存泄露对造成内存泄露的代码会被多次执行,每次被执行的时候都会导致一块内存泄露。偶发性和常发性内存泄露是相对而言的。对于使用不同的测试工具和测试算法,常发性可能会变成偶发性内存泄露,或者偶发性内存泄露也会变成常发性内存泄露。
(3)一次性内存泄露对造成内存泄露的代码只会被执行一次。比如,在初始化阶段,在类的构造函数中分配内存,但是在执行结束的阶段没有释放该内存,从而造成内存泄露的意外情况发生。
(4)隐式内存泄露程序在运行过程中不停地分配内存,但是没有及时释放,而是再等到执行结束的时候才会释放内存,严格地说,这种情况就会中造成内存泄露的发生。例如对于一个服务器,需要运行的时间很长,可能会长达几百天,如果存在隐式内存泄露,在最坏情况就会发生内存泄露。
从用户使用应用程序的角度来看,内存泄露是一种常见的现象,它本身不会产生非常重大的危害,甚至有一部分用户根本感觉不到内存泄露的发生。但是真正危害之处在于,这种内存泄露现象的堆积,最终会消耗尽系统所有的内存。因此,具有良好的编程习惯和采取严格的软件测试对于避免内存泄露是一种非常有效的方式。
责任编辑:hnmd003
相关阅读
-
小米Redmi A58 2022智能电视开售 金属全面屏设计屏占比达95.4%
今日上午10点,小米 Redmi A58 2022智能电视正式开售,首发价为1599元。Redmi A58 2022 电视配备...
2022-04-28 -
iQOO Neo6 SE预热 支持双电芯80W闪充30分钟充至100%
今日,官方再次对iQOO Neo6 SE预热,官方称,iQOO Neo6 SE支持双电芯80W闪充,至快30分钟充至100%。...
2022-04-28
相关阅读
-
内存溢出是什么 内存溢出的原因和解决方法
内存溢出(Out Of Memory,简称OOM)是指应用系统中存在无法回收的内存或使用的内存过多,最终使得程序...
-
ai是什么文件 ai文件怎么打开
ai 格式文件是Adobe公司发布的 AdobeIllustrator制作生成的矢量图文件。它的优点是占用硬盘空间小,打...
-
csv文件是什么意思 csv文件用什么打开
CSV文件是电子表格程序常用的逗号分隔值文件。它包含以逗号分隔的纯文本数据集,CSV 文件中的每个新行...
-
北京发放首批乘用车无人化示范应用道路测试通知书 百度成首家
4月28日消息,北京发放首批乘用车无人化示范应用道路测试通知书,百度成为首家获准企业。百度旗下自动驾...
-
火狐浏览器承诺不卖给亿万富翁 背后最大支持者是谷歌
近日,推特被马斯克以 440 亿美元价格收购,这一行为也遭到部分人的反对,火狐就是其中一个。日前,火...
-
NASA发布未来十年重要探测任务:30年代初发射天王星探测器
据英国《自然》杂志网站近日报道,美国行星科学家发布了一份内容翔实的报告,阐述了美国国家航空航天局(...
-
科学家发现生命的关键成分或由富碳陨石带到地球
英国《自然·通讯》杂志26日发表的一篇行星科学论文指出,对组成DNA和RNA必不可少的嘧啶碱基可能是由富...
-
郭明錤:苹果和硕昆山厂最早本周重启生产 产能恢复40%
苹果分析师郭明錤昨日发推指出,假设昆山疫情形势持续好转,和硕昆山厂最早将于本周在重启生产。根据零...
-
绿联发布100W智充魔盒Pro 内置氮化镓芯片
近日,绿联发布了100W智充魔盒Pro,配备3个AC强电接口和4个USB接口,内置氮化镓芯片,售价349元。据了解...
-
小鹏汽车获农业银行75亿元信贷额度 支持中国业务运营
有消息称,小鹏汽车从中国农业银行广东省分行获得了75亿元综合信贷额度,以支持该公司在中国的业务运营...
-
产品规格提升销量增加 联发科一季度营收同比增长32%
联发科昨日发布了2022年第一季度财报,财报显示,一季度营收1427亿新台币,同比增长32%。第 1 季营收...
-
小米Redmi A58 2022智能电视开售 金属全面屏设计屏占比达95.4%
今日上午10点,小米 Redmi A58 2022智能电视正式开售,首发价为1599元。Redmi A58 2022 电视配备...
-
曝神州优车61亿股权被冻结 执行法院为北京金融法院
天眼查信息显示,近日,神州优车(福建)信息技术有限公司新增股权冻结信息,被执行人为神州优车股份有限...
-
OPPO智能电视 K9x 65英寸开售 拥有10亿色彩4K分辨率
今日上午10点,OPPO智能电视 K9x 65英寸正式开售,首发价2199元。OPPO 新款 K9x 电视拥有 10 亿...
-
OPPO K10系列正式开售 首发联发科天玑8000-MAX处理器
今日上午10点,OPPO K10系列正式开售,新机售价1999元起。其中 OPPO K10 售价 1999 元起,OPPO K...
-
曝沙特计划订购5万至10万辆电动轿车 助力国家经济转向多样化
日前,沙特阿拉伯宣布,计划在未来十年内向电动汽车初创公司Lucid订购5万至10万辆电动汽车。Lucid 曾得...
-
联想中国发布新IT领航者计划 5年内达成千亿营收目标
4月28日,主题为风云际会 共赢新IT的2022联想中国商用大客户合作伙伴大会在北京召开。据悉,会议现场,...
-
摩托罗拉Edge 30发布 配备高通骁龙778G Plus处理器支持33W快充
有消息称,摩托罗拉 Moto Edge 30已经在部分地区开售,配备了高通骁龙 778G Plus处理器。摩托罗拉...
-
Meta一季度营收279.1亿美元 股价盘后涨超13%
Facebook母公司Meta周三盘后公布了该公司一季度财报。财报显示,一季度营收279 1亿美元,同比增长7%。M...
-
iQOO Neo6 SE预热 支持双电芯80W闪充30分钟充至100%
今日,官方再次对iQOO Neo6 SE预热,官方称,iQOO Neo6 SE支持双电芯80W闪充,至快30分钟充至100%。...
-
高通第二财季营收111.64亿美元 盘后股价涨逾5%
高通今日发布了该公司的2022财年第二财季财报,财报显示,高通第二财季营收111 64亿美元,同比增长41%...
-
苹果推出自助维修服务 可提供200多种零件和工具
昨日,苹果宣布自助维修服务现已推出,客户可通过Apple自助维修店获取维修手册和原装Apple零件和工具。...
-
刘强东对新能源车寄予厚望并逐步将物流车换成新能源车
以新技术和新材料为基础,使传统的可再生能源得到现代化的开发和利用,用取之不尽,用之不竭的可再生资源如...
-
供应链危机席卷汽车业 精益生产模式该改变了吗?
短期内千方百计地增加零部件库存可能是最好的办法,但增加成本又跟精益生产相悖,可特殊历史时期下又能...
-
杭州集中供地59宗地块成交 平均溢价率3.6%
4月25日,杭州首轮集中供地正式开拍,本轮集中供地共计60宗地块,总规划建面580 7万平方米,总起始金额...
-
天津首轮集中供地收官 15宗地块仅6宗成交
4月25日,天津首轮集中供地收官,本轮集中供地共计15宗地块,最终仅6宗地成交,总成交金额约43 5亿元,...
-
广州一季度房地产投资同比增长12.7% 投资结构持续优化
4月26日,广州市统计局公布一季度全市固定资产投资情况。数据显示,一季度,广州全市完成固定资产投资额...
-
天津:首套住房贷款最高限额上调至80万元
近日,天津市住房公积金管理中心发布《关于调整公积金的相关政策的征求意见稿》(以下简称《意见稿》)。...
-
海门推广示范基地:高氧气调包装技术助力猪肉品质提升
想要延长分割猪肉产品货架期,合理有效的保鲜技术是关键,目前气调包装技术逐渐发挥越来越重要的作用,...
-
扬州农商银行首季开门红 存贷款余额新增82亿元
一季度以来,扬州农商银行坚决落实省联社的决策部署,紧紧围绕首季开门红的目标任务,积极作为,奋勇争...
精彩推荐
阅读排行
精彩推送
- 恒誉环保(688309)今日复牌 20...
- A股迎来强势反弹行情 赛道股率...
- 可靠股份(301009)年报与一季报...
- 物丰价稳!盱眙居民的“菜篮子”...
- 盱眙稳步推进老旧小区改造 今年...
- 溧水:聚力聚势打好人才“引育留...
- 28家规上企业订单激增 高淳淳溪...
- 股市走弱股民被套 股民被套的几...
- 战“疫”纾困征管“硬举措” 镇...
- 助力双碳目标实现 顺风车碳减排...
- 农民卖扣碗被罚五万 售自制菜引...
- 租赁住房首次纳入公共消费 住房...
- 全国首个!江苏预制菜点质量评价...
- 行长被查资产质量下滑 招商银行...
- 短线交易是什么意思 怎样做好短...
- 信用卡免息分期有手续费吗?可以...
- 信用卡欠款减免申请书怎么写?有...
- 找律师协商信用卡逾期需要多少钱...
- 和泰人寿保险公司怎么样?值得信...
- 和泰人寿超级玛丽6号坑?与达尔...
- 和泰人寿鑫享盈?和泰人寿鑫享盈...
- 和泰人寿保险可靠吗?旗下产品有...
- 和泰人寿保险公司排名多少?是靠...
- 重大疾病险交满20年后怎样办?退...
- 中国人寿退保几天能拿到钱?能退...
- 和泰人寿增多多增额终身寿险是真...
- 和泰人寿保险靠谱吗?旗下产品怎...
- 节能环保股票的龙头股都有哪些?...
- 和泰人寿怎么样?和泰人寿和信泰...
- 疫苗板块上市公司2022年有哪些(...