背景

最近准备上线cassandra这个产品,同事在做一些小规格ECS(8G)的压测。压测时候比较容易触发OOM Killer,把cassandra进程干掉。问题是8G这个规格我配置的heap(Xmx)并不高(约6.5g)已经留出了足够的空间给系统。只有可能是Java堆外内存使用超出预期,导致RES增加,才可能触发OOM。

调查过程

0.初步怀疑是哪里有DirectBuffer泄漏,或者JNI库的问题。
1.按惯例通过google perftools追踪堆外内存开销,但是并未发现明显的异常。
2.然后用Java NMT 看了一下,也没有发现什么异常。

3.查到这里思路似乎断了,因为跟DirectBuffer似乎没啥关系。这时候我注意到进程虚拟内存非常高,已经超过ECS内存了。怀疑这里有些问题。

4.进一步通过/proc/pid/smaps 查看进程内存地址空间分布,发现有大量mmap的文件。这些文件是cassandra的数据文件。

此时这些mmap file 虚拟内存是2G,但是物理内存是0(因为我之前重启过,调低过内存防止进程挂掉影响问题排查)。

显然mmap的内存开销是不受JVM heap控制的,也就是堆外内存。如果mmap的文件数据被从磁盘load进物理内存(RES增加),Java NMT和google perftool是无法感知的,这是kernel的调度过程。

5.考虑到是在压测时候出现问题的,所以我只要读一下这些文件,观察下RES是否会增加,增加多少,为啥增加,就能推断问题是不是在这里。通过下面的命令简单读一下之前导入的数据。

cassandra-stress read duration=10m cl=ONE -rate threads=20 -mode native cql3 user=cassandra password=123 -schema keysp
ace=keyspace5 -node core-3

6.可以观察到压测期间(sar -B),major page fault是明显上升的,因为数据被实际从磁盘被load进内存。

同时观察到mmap file物理内存增加到20MB:

最终进程RES涨到7.1g左右,增加了大约600M:

如果加大压力(50线程),还会涨,每个mmap file物理内存会从20MB,涨到40MB

7.Root cause是cassandra识别系统是64还是32来确定要不要用mmap,ECS都是64,但是实际上小规格ECS内存并不多。

结论

1.问题诱因是mmap到内存开销没有考虑进去,具体调整方法有很多。可以针对小规格ECS降低heap配置或者关闭mmap特性(disk_access_mode=standard)

2.排查Java堆外内存还是比较麻烦的,推荐先用NMT查查,用起来比较简单,配置JVM参数即可,可以看到内存申请情况。

本文作者:Roin

原文链接

本文为云栖社区原创内容,未经允许不得转载。

实战经验 | Cassandra Java堆外内存排查经历全记录的更多相关文章

  1. 超干货!Cassandra Java堆外内存排查经历全记录

    背景 最近准备上线cassandra这个产品,同事在做一些小规格ECS(8G)的压测.压测时候比较容易触发OOM Killer,把cassandra进程干掉.问题是8G这个规格我配置的heap(Xmx ...

  2. google-perftools 分析JAVA 堆外内存

    google-perftools 分析JAVA 堆外内存 分类: j2se2011-08-25 21:48 3358人阅读 评论(4) 收藏 举报 javahbasehtml工具os 原文转自:htt ...

  3. Java堆外内存管理

    Java堆外内存管理   1.JVM可以使用的内存分外2种:堆内存和堆外内存: 堆内存完全由JVM负责分配和释放,如果程序没有缺陷代码导致内存泄露,那么就不会遇到java.lang.OutOfMemo ...

  4. Java堆外内存之二:堆外内存使用总结

    目录: <堆外内存操作类ByteBuffer> <DirectBuffer> <Unsafe(java可直接操作内存(),挂起与恢复,CAS操作)> 有时候对内存进 ...

  5. Java堆外内存之六:堆外内存溢出问题排查

    一.堆外内存组成 通常JVM的参数我们会配置 -Xms 堆初始内存 -Xmx 堆最大内存 -XX:+UseG1GC/CMS 垃圾回收器 -XX:+DisableExplicitGC 禁止显示GC -X ...

  6. Java堆外内存之突破JVM枷锁

    对于有Java开发经验的朋友都知道,Java中不需要手动的申请和释放内存,JVM会自动进行垃圾回收:而使用的内存是由JVM控制的. 那么,什么时机会进行垃圾回收,如何避免过度频繁的垃圾回收?如果JVM ...

  7. Java堆外内存之七:JVM NativeMemoryTracking 分析堆外内存泄露

    Native Memory Tracking (NMT) 是Hotspot VM用来分析VM内部内存使用情况的一个功能.我们可以利用jcmd(jdk自带)这个工具来访问NMT的数据. NMT介绍 工欲 ...

  8. Java堆外内存之一:堆外内存场景介绍(对象池VS堆外内存)

    最近经常有人问我在Java中使用堆外(off heap)内存的好处与用途何在.我想其他面临几样选择的人应该也会对这个答案感兴趣吧. 堆外内存其实并无特别之处.线程栈,应用程序代码,NIO缓存用的都是堆 ...

  9. Java堆外内存的使用

    堆外内存的回收见HeapByteBuffer和DirectByteBuffer以及回收DirectByteBuffer 基本类型长度 在Java中有很多的基本类型,比如: byte,一个字节是8位bi ...

随机推荐

  1. 2018-11-19-WPF-在image控件用鼠标拖拽出矩形

    title author date CreateTime categories WPF 在image控件用鼠标拖拽出矩形 lindexi 2018-11-19 15:35:13 +0800 2018- ...

  2. CVE-2016-0095提权漏洞分析

    1 前言 瞻仰了k0shl和鹏哥 的漏洞分析,感慨万千,任重而道远. 2 系统环境和工具 windows 7 32旗舰版 windbg 3 poc 3.1poc复现 首先k0shl大佬给出的poc() ...

  3. mysql主从复制linux配置(二进制日志文件)

    安装mysql,两台机器一主(192.168.131.153),一从(192.168.131.154) 主机配置 修改主/etc/my.cnf文件 添加 #server_id=153 ###服务器id ...

  4. 【JZOJ3237】间谍派遣

    description 你是M,一个雇佣N个标号为从1到N的间谍的情报机关的总管.每个间谍被派往不同的国家并在那获取重要情报. 如下是你的任务: 1.在部分间谍间组织会面.每次会面在两个间谍间进行,两 ...

  5. dvajs+antd定制主题踩坑记录

    记一下刚刚解决的问题,困扰了几周,期间困兽争斗,甚至想放弃antd组件库.终于出来了,人类科技又进步了(才怪). 首先我按照dva官网建立了项目.里面引入antd的各种组件,因为需要用到一个switc ...

  6. Joomla - 后台系统(功能简介)

    Joomla - 后台系统简介 全局配置

  7. Ubuntu 12.04 Eclipse设置 Javadoc背景色

    在Ambiance主题下,eclipse弹出的tip是黑色背景的,这样压根就看不清java doc. 当然可以在外观改变系统主题为其他主题,相应的gtk-2.0/gtkrc要重新设置,比如Ubuntu ...

  8. 深入浅出 Java Concurrency (28): 线程池 part 1 简介[转]

    从这一节开始正式进入线程池的部分.其实整个体系已经拖了很长的时间,因此后面的章节会加快速度,甚至只是一个半成品或者简单化,以后有时间的慢慢补充.完善. 其实线程池是并发包里面很重要的一部分,在实际情况 ...

  9. LINQ学习系列-----3.1 查询非泛型集合和多个分组

    一.查询非泛型集合 1.问题起源 LINQ to object在设计时,是配合IEnumerable<T>接口的泛型集合类型使用的,例如字典.数组.List<T>等,但是对于继 ...

  10. c++ STL使用

    STL标准模板库,提供一些类似java集合类的数据结构容器.比如eque.list.vector.map 等.还提供一些支持这些容器的算法和遍历容器的迭代器. 使用方法 #include <io ...