前往小程序,Get更优阅读体验!
立即前往
首页
学习
活动
专区
圈层
工具
发布
首页
学习
活动
专区
圈层
工具
MCP广场
社区首页 >专栏 >OutOfMemoryError系列: Java heap space错误深度解析

OutOfMemoryError系列: Java heap space错误深度解析

作者头像
ImportSource
发布于 2018-04-03 06:28:32
发布于 2018-04-03 06:28:32
9K00
代码可运行
举报
文章被收录于专栏:ImportSourceImportSource
运行总次数:0
代码可运行

本文包括JVM内存管理、错误产生的原因、内存泄漏的代码示例,最后还会介绍怎么解决这些问题,特别会提到一些性能诊断工具,让你快速的知道问题发生的根本原因。

java.lang.OutOfMemoryError:Java heap space

java的应用程序只被允许使用限定好的memory。在java的application启动的时候,这个内存大小就被规定好了。为了让内存管理更加的智慧,java的memory被分为了两个不同的区域。这两个区域分别被叫做heap space和Permanent Generation(很多书中叫“永久代”)。

这两个区域的大小在JVM启动的时候就被设置好了,是通过两个JVM参数-Xmx and -XX:MaxPermSize来设置的,如果你不专门去设置这两个的大小,那么将会使用平台定义好的默认值。

java.lang.OutOfMemoryError:java heap space 这个错误是在什么情况下发生呢?就是当你的application想要往heap那个空间里添加更多的数据的时候,但heap里却没有足够的空置区域的时候就会发生java heap space错误。

请注意,也许还有足够的物理内存,但是当JVM达到heap的大小限制时,就会抛出java.lang.OutOfMemoryError: Java heap space 错误。

怎么引起的?

java.lang.OutOfMemoryError这个错误的产生最常见的原因其实很简单:就是你的应用程序需要更多的 heap 空间。引起这个错误的其他原因就比较复杂了,可能是因为你的编程错误引起的,比如下面两种情况:

  • 使用/数据量的峰值。该应用程序旨在处理一定数量的用户或一定量的数据。当用户数量或数据量突然突增并超过预期阈值时,在尖峰停止操作之前正常运行的操作会触发java.lang.OutOfMemoryError:Java heap space 错误。
  • 内存泄漏(Memory leaks)。特定类型的编程错误将导致您的应用程序不断消耗更多的内存。每次应用程序的那个带有泄漏问题的函数被调用的时候,它就会将一些对象留在Java heap space中。随着时间的推移,那些被泄漏的对象会消耗掉所有可用的Java heap space,并触发这个你已很熟悉的java.lang.OutOfMemoryError:Java heap space 错误。

上代码 简单的例子:

第一个例子很简单 - 下面的Java代码试图分配一个2M整数的数组。 当你编译它并使用12MB的Java堆空间(java -Xmx12m OOM)启动时,它会失败,并返回java.lang.OutOfMemoryError:Java heap space 消息。 使用13MB的Java堆空间,程序就运行正常了。

代码语言:javascript
代码运行次数:0
运行
AI代码解释
复制
class OOM {
  static final int SIZE=2*1024*1024;
  public static void main(String[] a) {
    int[] i = new int[SIZE];
   }
}

内存泄露的例子:

第二个更现实的例子是内存泄漏。在Java中,当开发人员创建和使用新对象new Integer(5),他们不必自己分配内存 - 这是由Java虚拟机(JVM)来处理。在应用程序的生命周期中,JVM会定期检查内存中的哪些对象仍在使用,哪些不是。未使用的对象可以被丢弃,内存被回收并再次使用。这个过程称为垃圾收集。 JVM中处理集合的相应模块称为垃圾回收器(GC)。

Java的自动内存管理依赖于GC定期查找未使用的对象并删除它们。简化一点我们可以说,Java中的内存泄漏是一种情况,其中一些对象不再由应用程序使用,但垃圾收集无法识别它。因此,这些未使用的对象将无限期地保留在Java堆空间中。这个堆积将最终触发java.lang.OutOfMemoryError:Java heap space 错误。

构造一个满足内存泄漏定义的Java程序是相当容易的,像下面这样:

代码语言:javascript
代码运行次数:0
运行
AI代码解释
复制
class KeylessEntry {
 
   static class Key {
      Integer id;
 
      Key(Integer id) {
         this.id = id;
      }
 
      @Override
      public int hashCode() {
         return id.hashCode();
      }
   }
 
   public static void main(String[] args) {
      Map m = new HashMap();
      while (true)
         for (int i = 0; i < 10000; i++)
            if (!m.containsKey(new Key(i)))
               m.put(new Key(i), "Number:" + i);
   }
}

当你执行上面的代码,你也许希望它一直没问题的运行下去,并且认为这个缓存方案仅仅会增加到10000个key。然而事实是 key会一直被增加,因为Key这个class里边并没有包含equals()的实现,只是override了hashCode()方法。

最后,随着时间的推移,随着泄漏代码的不断使用,“缓存”结果最终消耗了大量的Java堆空间。 当泄漏的内存填满堆区域中的所有可用内存,并且Garbage Collection无法清除它时,会抛出java.lang.OutOfMemoryError:Java heap space 。

要想内存不再泄漏,其实办法很简单-就是加上 equals()方法的实现,像下面这样:

代码语言:javascript
代码运行次数:0
运行
AI代码解释
复制
@Override
public boolean equals(Object o) {
   boolean response = false;
   if (o instanceof Key) {
      response = (((Key)o).id).equals(this.id);
   }
   return response;
}

怎么解决呢?

在某些情况下,你分配给JVM的heap数量不足以满足在该JVM上运行的应用程序的需求。 在这种情况下,你只需要分配更多的heap就可以了 - 请参见本章末尾如何实现。

然而,在许多情况下,提供更多的Java堆空间不会解决问题。 例如,如果您的应用程序包含内存泄漏,添加更多堆将只是推迟java.lang.OutOfMemoryError:Java heap space 错误。 此外,增加Java堆空间量也会增加影响应用程序吞吐量或延迟的GC暂停时间。

如果你想解决Java堆空间的根本问题,而不是掩盖症状,你需要找出那些分配了最多的内存的那些代码。 换句话说,你需要回答这些问题:

1.哪些对象占用了heap的大部分?

2.这些对象分布在源码中的哪个地方?

此时,你要花上一些时间来解决这些问题了。这里是一个粗略的过程大纲,将帮助您回答上述问题:

获取安全许可,以便从JVM中把heap中的内容dump出来存储到另外一个地方。 “Dumps”基本上就是堆内容的一个快照,你稍后就是在这些dumps中进行分析。由于这些快照可能包含机密信息,例如密码,银行卡号等,所以你必须要获得安全部门的允许。

选择在一个合适的时间进行dump(转储)操作。如果时机不对,堆垃圾可能包含大量的噪音,甚至可能几乎没有什么有用的信息。另一方面,每个堆的dump(转储)会完全“冻结”JVM,这样会占用过多的JVM,这种情况下很可能会影响正常业务的访问,会出现一些性能问题。

专门找一台机器用作dump(转储)。当你要分析8GB的堆,那你就要一台超过8GB的机器来分析堆内容。然后选择一个转储分析软件(我们建议使用Eclipse MAT,你也可以选择其他转储分析软件)。

检测出堆的最大消费者的GC根的路径。我们在这里单独的一篇文章中介绍了这项活动。

接下来,你需要确定源代码中的哪些位置正在分配潜在危险的大量对象。如果你对应用程序的源代码很了解的话,你将能够在几次搜索中做到这一点。

或者,我们建议你使用Plumbr,这是一个jvm性能检测工具,它可以自动检测出问题的根本原因。 在其他性能问题上,它同样可以捕获所有java.lang.OutOfMemoryErrors,并且可以自动的为你整理出那些非常“内存饥饿”(memory-hungry)的数据结构的信息。

Plumbr会在幕后为你收集必要的数据 - 包括有关堆使用的相关数据(只有对象布局图,没有实际数据),以及一些在“堆转储”(heap dump)中找不到的数据。 如果JVM遇到java.lang.OutOfMemoryError,Plumbr还会为您执行必要的数据处理 。 下面是一个Plumbr的有关java.lang.OutOfMemoryError错误的一个例子(分析结果):

没有任何额外的工具或分析,你就可以看到:

  • 哪些对象消耗的内存最多(271个com.example.map.impl.PartitionContainer实例在248MB的总堆中消耗173MB)
  • 这些对象是在哪个类中被分配的?(大多数在MetricManagerImpl类中分配,行304)
  • 当前引用这些对象的完整引用链(GC引用的完整引用链)

有了这些信息,您就可以找到问题的根本原因了,然后把数据结构修剪到它们适合在您的内存池中的级别。

但是,当您从内存分析或阅读Plumbr报告得出的结论是内存使用是合法的,那么就没必要修改源代码了,这时候你就要设置更大的java heap 空间来保证应用程序的运行了。 请更改JVM启动配置,并添加(或增加值,如果存在)以下内容:

-Xmx1024m

上面的配置将给应用程序1024MB的 Java heap space。 您可以使用g或G表示GB,m或M表示MB,k或K表示KB。 例如,下面的几种方式都表示最大Java heap space为1GB:

代码语言:javascript
代码运行次数:0
运行
AI代码解释
复制
    java -Xmx1073741824 com.mycompany.MyClass
    java -Xmx1048576k com.mycompany.MyClass
    java -Xmx1024m com.mycompany.MyClass
    java -Xmx1g com.mycompany.MyClass
本文参与 腾讯云自媒体同步曝光计划,分享自微信公众号。
原始发表:2016-10-30,如有侵权请联系 cloudcommunity@tencent.com 删除

本文分享自 ImportSource 微信公众号,前往查看

如有侵权,请联系 cloudcommunity@tencent.com 删除。

本文参与 腾讯云自媒体同步曝光计划  ,欢迎热爱写作的你一起参与!

评论
登录后参与评论
暂无评论
推荐阅读
Python中的NLP
自然语言处理(NLP)是数据科学中最有趣的子领域之一,数据科学家越来越期望能够制定涉及利用非结构化文本数据的解决方案。尽管如此,许多应用数据科学家(来自STEM和社会科学背景)都缺乏NLP经验。
February
2018/11/30
4K1
如何用Python处理自然语言?(Spacy与Word Embedding)
本文教你用简单易学的工业级Python自然语言处理软件包Spacy,对自然语言文本做词性分析、命名实体识别、依赖关系刻画,以及词嵌入向量的计算和可视化。
王树义
2018/08/22
2.6K0
如何用Python处理自然语言?(Spacy与Word Embedding)
NLP入门+实战必读:一文教会你最常见的10种自然语言处理技术(附代码)
大数据文摘作品 编译:糖竹子、吴双、钱天培 自然语言处理(NLP)是一种艺术与科学的结合,旨在从文本数据中提取信息。在它的帮助下,我们从文本中提炼出适用于计算机算法的信息。从自动翻译、文本分类到情绪分析,自然语言处理成为所有数据科学家的必备技能之一。 在这篇文章中,你将学习到最常见的10个NLP任务,以及相关资源和代码。 为什么要写这篇文章? 对于处理NLP问题,我也研究了一段时日。这期间我需要翻阅大量资料,通过研究报告,博客和同类NLP问题的赛事内容学习该领域的最新发展成果,并应对NLP处理时遇到的各类状
大数据文摘
2018/05/24
1.6K0
从“London”出发,8步搞定自然语言处理(Python代码)
【新智元导读】自然语言处理是AI的一个子领域,从人们日常沟通所用的非结构化文本信息中提取结构化数据,以便计算机理解。本文用通俗易懂的语言深入浅出的介绍了自然语言处理,并用Python实现了几个非常有趣的实例。
新智元
2018/08/16
9470
从“London”出发,8步搞定自然语言处理(Python代码)
独家 | 快速掌握spacy在python中进行自然语言处理(附代码&链接)
本文简要介绍了如何使用spaCy和Python中的相关库进行自然语言处理(有时称为“文本分析”)。以及一些目前最新的相关应用。
数据派THU
2019/10/29
3.4K0
独家 | 快速掌握spacy在python中进行自然语言处理(附代码&链接)
NLP揭秘:从自然语言处理的角度出发,女儿也是灭霸的真爱
《复仇者联盟4:终局之战》仍在热映中。在看到大结局的同时,本文将带你通过数据科普的眼光来回顾《复仇者联盟3:无限战争》:看看这群世界上最强的超级英雄们最爱说的词汇是哪些?
商业新知
2019/05/16
1.1K0
NLP揭秘:从自然语言处理的角度出发,女儿也是灭霸的真爱
NeuralCoref: 用指代消解来做一个“能多轮对话的问答对话机器人”
版权声明:本文为博主原创文章,遵循 CC 4.0 BY-SA 版权协议,转载请附上原文出处链接和本声明。
blmoistawinde
2019/10/30
1.7K0
Python自然语言处理面试:NLTK、SpaCy与Hugging Face库详解
NLTK、SpaCy与Hugging Face库作为Python自然语言处理(NLP)领域的三大主流工具,其理解和应用能力是面试官评价候选者NLP技术实力的重要标准。本篇博客将深入浅出地探讨Python NLP面试中与NLTK、SpaCy、Hugging Face库相关的常见问题、易错点,以及如何避免这些问题,同时附上代码示例以供参考。
Jimaks
2024/04/19
3680
用spaCy自然语言处理复盘复联无限战争(上)
《复仇者联盟4:终极游戏》已经上映不短的时间,我,和世界上大多数人一样,在第一时间冲到电影院去看,体验《复仇4》是如何拯救世界并且结束第一个十年的故事的。为了平息我的紧张情绪,缓解等待,我想重温上一部电影《复联3:无限战争》,当然,由于我是一个搞技术的,我的回顾旅行将用到的是自然语言处理,简称NLP。
AiTechYun
2019/05/29
6620
用spaCy自然语言处理复盘复联无限战争(上)
Python文本预处理:步骤、使用工具及示例
本文将讨论文本预处理的基本步骤,旨在将文本信息从人类语言转换为机器可读格式以便用于后续处理。此外,本文还将进一步讨论文本预处理过程所需要的工具。
AI科技大本营
2019/05/06
1.7K0
Python文本预处理:步骤、使用工具及示例
一文带你读懂自然语言处理 - 事件提取
每天产生的文本信息令人叹为观止。数百万数据源以新闻稿、博客、消息、手稿和无数其他形式发布,因而自动组织和处理就必不可少。
AI研习社
2019/05/15
1.5K0
一文带你读懂自然语言处理 - 事件提取
5个Python库可以帮你轻松的进行自然语言预处理
自然语言是指人类相互交流的语言,而自然语言处理是将数据以可理解的形式进行预处理,使计算机能够理解的一种方法。简单地说,自然语言处理(NLP)是帮助计算机用自己的语言与人类交流的过程。
deephub
2021/05/18
9480
【独家】自然语言处理(NLP)入门指南
致谢 钟崇光博士参与了数据派THU于6月5日、THU数据派于6月8日发布的《循序渐进提升Kaggle竞赛模型精确度,以美国好事达保险公司理赔为例》一文的校对工作,并且给出了许多有建设性的意见,在此数据派翻译组对钟博士表达诚挚的感谢! 作者:Melanie Tosik 翻译:闵黎 校对:丁楠雅 本文长度为1100字,建议阅读3分钟 Melanie Tosik目前就职于旅游搜索公司WayBlazer,她的工作内容是通过自然语言请求来生产个性化旅游推荐路线。回顾她的学习历程,她为期望入门自然语言处理的初学者
数据派THU
2018/01/29
2K0
【独家】自然语言处理(NLP)入门指南
【AI】探索自然语言处理(NLP):从基础到前沿技术及代码实践
自然语言处理(NLP)是人工智能领域的一个重要分支,它使计算机能够理解、生成、分析和与人类语言进行交互。随着科技的不断发展,NLP技术得到了显著提升,尤其是在深度学习的帮助下,NLP正在越来越广泛地应用于各种领域,如搜索引擎、智能助手、机器翻译、语音识别和情感分析等。
云边有个稻草人
2025/02/03
2070
自然语言处理(NLP)——简介
自然语言处理(NLP Natural Language Processing)是一种专业分析人类语言的人工智能。就是在机器语⾔和⼈类语言之间沟通的桥梁,以实现人机交流的目的。 在人工智能出现之前,机器智能处理结构化的数据(例如Excel里的数据)。但是网络中 大部分的数据都是非结构化的,例如:文章、图片、音频、视频... 在非结构数据中,文本的数量是最多的,他虽然没有图片和视频占用的空间大,但是他的 信息量是最大的。 为了能够分析和利用这些文本信息,我们就需要利用NLP技术,让机器理解这些文本信息,并加以利用。
SpringSun
2021/07/14
2.8K0
自然语言处理(NLP)——简介
关于NLP你还不会却必须要学会的事儿—NLP实践教程指南第一编
作者 | Dipanjan (DJ) Sarkar 编译 | 姗姗 出品 | 人工智能头条(公众号ID:AI_Thinker) 【人工智能头条导读】在研究和处理自然语言处理的很多问题时,除了关注各种各样基础的数据,高级的深度学习模型、算法外,其实中间还涉及了很多处理技术,比如:词干提取、词形还原、句法分析、语义分析等,虽然不同的语言特征不同,但是这其中大部分步骤都是存在于大多数NLP领域任务中的。今天特别为大家准备了一篇包含NLP重要技术概念学习和实践的文章,希望无论是基础数据、技术理论还是代码实践大家都可
用户1737318
2018/07/20
1.9K0
使用Python中的NLTK和spaCy删除停用词与文本标准化
【磐创AI 导读】:本文介绍了如何使用Python中的NLTK和spaCy删除停用词与文本标准化,欢迎大家转发、留言。想要更多电子杂志的机器学习,深度学习资源,大家欢迎点击上方蓝字关注我们的公众号:磐创AI。
磐创AI
2019/09/09
4.3K0
使用Python中的NLTK和spaCy删除停用词与文本标准化
入门 | 自然语言处理是如何工作的?一步步教你构建 NLP 流水线
计算机非常擅长使用结构化数据,例如电子表格和数据库表。但是我们人类通常用文字交流,而不是使用电子表格来交流。这对计算机来说不是一件好事。
机器之心
2018/08/21
1.7K0
入门 | 自然语言处理是如何工作的?一步步教你构建 NLP 流水线
Python 自然语言处理实用指南:第一、二部分
在本节中,您将在自然语言处理(NLP)的背景下了解 PyTorch 1.x 的基本概念。 您还将学习如何在计算机上安装 PyTorch 1.x,以及如何使用 CUDA 加快处理速度。
ApacheCN_飞龙
2023/04/27
1.4K0
深度 | 你知道《圣经》中的主要角色有哪些吗?三种NLP工具将告诉你答案!
在思考数据科学的时候,我们常常想起数字的统计分析。但是,各种组织机构越来越频繁地生成大量可以被量化分析的非结构文本。一些例子如社交网络评论、产品评价、电子邮件以及面试记录。
机器之心
2018/07/26
1.7K0
深度 | 你知道《圣经》中的主要角色有哪些吗?三种NLP工具将告诉你答案!
推荐阅读
相关推荐
Python中的NLP
更多 >
领券
问题归档专栏文章快讯文章归档关键词归档开发者手册归档开发者手册 Section 归档