专栏首页java一日一条内存不足:杀死进程还是牺牲子进程

内存不足:杀死进程还是牺牲子进程

早上6点,我不得不开始处理“叫醒”我的一些问题。因为当这些问题发生的时候,我的手机铃声响了。昏睡中的我非常不情愿地拿起了手机,检查我是否疯狂到将叫醒闹钟设在了早上5点。原来是监控系统发现一个Plumbr服务死掉了。

作为一名该领域经验丰富的高手,我首先来到了咖啡机旁。我需要用一杯咖啡开始工作。第一个问题,在应用崩溃之前看起来一切运行正常。日志中没有错误,没有告警,也没有其他任何异常。

我们的监控系统已经察觉到进程死掉了,并且已经重启了崩溃的服务。因为血液中已经有了咖啡因,我开始收集更多的证据。30分钟后,在/var/log/kern.log文件中发现了以下内容:

很显然,我们成了Linux内核的受害者。大家都知道,Linux建立在一些守护进程之上。这些守护进程被几个看起来糟透了的内核任务看管。所有现代Linux内核都内置了一个被称为“内存不足杀手”的机制,它在内存不足的情况下会杀掉用户进程。当检测到内存不足时,杀手会被激活并选择一个进程杀死。选择机制是用启发式算法对所有进程进行打分,最后选择得分最低的进程杀死。

理解“内存不足杀手”

默认情况下,Linux内核允许进程请求比当前系统可用内存更多的内存。这是有道理的,因为大部分进程从来不会用掉它们请求的所有内存。就像有线网络运营商,他们承诺每个用户100Mbit的下载速度,这远远超出了运营商网络的真实带宽。因为他们认为所有用户不会同时达到带宽的上限。所以,一个10Gbit的链路能够很好地为100个用户提供服务超。

这种机制的一个副作用是,一些程序会消耗系统内存。这将导致内存不足,使得没有内存页面可以分配给进程。你可能遇到过这种情况,只有root账号才能杀掉offending任务。为了避免这种情况发生,杀手进程会被启动,识别进程并杀死它。

内存不足杀手由谁触发?

现在,我们知道了一些背景知识,但是内存不足杀手由谁触发?究竟什么原因让我在早上5点被叫醒?一些调查显示:

  • /proc/sys/vm/overcommit_memory中的配置允许过量使用内存,它被设置为1,意味着每一次malloc都能够成功申请到内存。
  • 应用运行在一个EC2 m1.small实例上。EC2实例默认是不支持交换区的。

这两点再加上突然增加的访问导致了我们的应用会申请越来越多的内存以支持这些用户。过量使用内存配置也允许为这些进程申请越来越多的内存,最后触发了“内存不足杀手”,就像它的名字那样,杀死我们的应用然后在半夜把我叫醒。

示例

当我向工程师们描述这个问题时,有一个很有兴趣的工程师用一个小测试程序来复现这个问题。当在Linux(最新稳定版Ubuntu)上编译和加载下面的Java代码片段时,

你会发现类似下面的消息:Kill process (java) score 或牺牲子进程的消息。

注意:你可能需要修改交换区和堆大小。在我的测试程序中,将堆大小通过-Xmx2g设置成2G,通过如下配置设置交换区大小:

解决方案?

有很多种方法可以解决这个问题。在我们的示例中,我们只是把系统迁移到一个有更大内存的实例中。并且我还建议允许交换,但是当咨询过工程人员后,我意识到Java虚拟机中的垃圾回收进程在交换时表现不是很好,所以这个选项最后没有被采用。

其他可能有用的方案包括微调内存不足杀手,在几个实例间进行负载均衡或者降低应用的内存需求。

本文分享自微信公众号 - java一日一条(mjx_java),作者:收听我

原文出处及转载信息见文内详细说明,如有侵权,请联系 yunjia_community@tencent.com 删除。

原始发表时间:2016-07-11

本文参与腾讯云自媒体分享计划,欢迎正在阅读的你也加入,一起分享。

我来说两句

0 条评论
登录 后参与评论

相关文章

  • JavaScript 内存泄露的4种方式及如何避免

    本文将探索常见的客户端 JavaScript 内存泄露,以及如何使用 Chrome 开发工具发现问题。

    哲洛不闹
  • 上线即被封杀,王欣的匿名社交软件马桶MT长什么样?

    1月15号堪称是张小龙演讲后产品经理们的第二个小春晚,因为这一天,将有三款社交产品于同日召开发布会,而他们的母公司则分别为字节跳动、子弹短信以及王欣旗下的云歌智...

    哲洛不闹
  • 40+个对初学者非常有用的PHP技巧(二)

    考虑使用ob_gzhandler?不,别这样做。它没有任何意义。PHP应该是来写应用程序的。不要担心PHP中有关如何优化在服务器和浏览器之间传输的数据。

    哲洛不闹
  • Ubuntu Desktop基本办公环境搭建

    Ubuntu Desktop基本办公环境搭建 一如前面所强调的, linux系统是面向开发人员友好的,而对office办公人员并不友好 。 如果是重度的offi...

    用户1170933
  • 生产者和消费者模型

    生产者消费者模型具体来讲,就是在一个系统中,存在生产者和消费者两种角色,他们通过内存缓冲区进行通信,生产者生产消费者需要的资料,消费者把资料做成产品。

    希希里之海
  • 虐面试官系列Lifecyele 篇 -(1)基础知识

    又是很久很久没写文章了,最近打算写下Android的又一基础知识: Android 官方架构组件系列。打算把相关的知识点都整理写下,所以本系列的主体为Lifec...

    青蛙要fly
  • 【redis】redis内存管理、淘汰机制、内存优化

    如果想要运行一个内存高效的 Redis 数据库,首先需要理解那些在 redis.conf 配置文件中所有内存相关的指令。redis.conf 文件为大多数指令提...

    看、未来
  • TodoBackend展示应用以及ActFramework的实现

    老码农
  • 希尔排序

    希尔排序是对直接插入排序的改进,其实质就是分组插入排序,该方法又称缩小增量排序。 该算法的基本思想是:先将整个待排元素序列分割成若干个子序列(由相隔某个“增...

    卡尔曼和玻尔兹曼谁曼
  • leetcode407. Trapping Rain Water II

    神仙题。能够想出来用优先队列和广度优先遍历结合的都是大佬。希望所有看到这道题目的可以在文章回复里面分享一下写这题的思路。在下面我就粘贴一下根据油管上的思路写成的...

    眯眯眼的猫头鹰

扫码关注云+社区

领取腾讯云代金券