[转帖]直接内存监控不准确,netty玩了什么花?
https://segmentfault.com/a/1190000044509636
是挺久没有“宠爱”我们netty小婊贝了,最近又开始搞事了。
于是,趁机探究了下MXBean关于direct memory的监控原理。
一、问题
通过arthas dashboard中的direct,visualvm的MBeans以及jmx获取的grafana监控都无法看到直接内存有大量占用,但实际上应用已经在OOM的边缘。
······
那难道拿这个“小可爱”没法了吗?只能祭出终极绝招:添加jvm启动参数-XX:NativeMemoryTracking=detail。
简单说一下NMT,NMT(本地内存跟踪)是JDK自带的功能,方法简单,可以用它跟踪JVM内存使用情况。使用方法:
1. 启用NMT(启动加参数):-XX:NativeMemoryTracking=detail
2. 简单的执行命令:jcmd $pid VM.native_memory detail
即可打印:Java Heap、Class、Thread、Code、GC、Compiler、Internal、Symbol、Native Memory Tracking、Arena Chunk 内存可用、已占用情况。
其中:Java Heap即-Xmx的设置和占用情况;
Thread包含线程数量和线程本身占用内存(-Xss乘以线程数量)的情况;
Internal包含直接内存(Direct Memory,受-XX:MaxDirectMemorySize限制)
二、MXBean监控直接内存案例
一般我们可以使用MXBean通过下面的方式获取直接内存的使用情况:
private static final Logger LOG = LoggerFactory.getLogger(MemoryStatics.class);
// direct memory
public static BufferPoolMXBean directMBean;
// mapped memory
public static BufferPoolMXBean mappedMXBean; static {
List<BufferPoolMXBean> bufferPoolMXBeans = ManagementFactory.getPlatformMXBeans(BufferPoolMXBean.class); for (BufferPoolMXBean mbean : bufferPoolMXBeans) {
if (mbean.getName().equals("direct")) {
directMBean= mbean;
} else {
mappedMXBean = mbean;
}
}
}
public void monitor() { while (true) {
assert directMBean != null;
LOG.info("buffer pool name: " + directMBean);
LOG.info("memory used: " + directMBean.getMemoryUsed());
LOG.info("max memory : " + directMBean.getTotalCapacity());
LOG.info("contain buffers : " + directMBean.getCount());
LOG.info("---------------------------------------");
try {
Thread.sleep(1000);
} catch (InterruptedException e) {
throw new RuntimeException(e);
}
}
arthas的mbean命令和visualvm的MBeans中的BufferPool原理上也是类似的。
三、BufferPoolMXBean底层原理
上面的案例中,通过getMemoryUsed、getTotalCapacity、getCount方法获取实际direct memory的使用情况。而真正的实现类是JDK的sun.management.ManagementFactoryHelper(JDK8) 【可以直接打印mbean对象,可以看见类似对象信息:sun.management.ManagementFactoryHelper$1@de2b39c】:
而上面这段代码可以看到有getName、getCount、getTotalCapacity等方法,其真正实现都是在java.nio.Bits中,实现如下:
Bits类中有几个静态成员,简单说明:
// 最大直接内存,默认和-Xmx配置的大小一样
private static volatile long maxMemory = VM.maxDirectMemory();
// 已使用的直接内存大小
private static final AtomicLong reservedMemory = new AtomicLong();
// 总的直接内存大小,小于等于maxMemory
private static final AtomicLong totalCapacity = new AtomicLong();
在使用java.nio.ByteBuffer.allocateDirect或者DirectByteBuffer主构造函数时,每次分配直接内存都会调用Bits类进行实际分配并更新reservedMemory和totalCapacity等值。
关于DirectByteBuffer可以看之前的一篇《从HotSpot源码理解DirectByteBuffer》
DirectByteBuffer主构造函数如下:
netty的直接内存分配
简单说明下netty的直接内存分配。netty直接内存分配最终是通过PlatformDependent实现的,这个类有个原子类的静态成员DIRECT_MEMORY_COUNTER独立进行内存使用记录,不依赖Bits.
// PlatformDependent直接内存记录器
private static final AtomicLong DIRECT_MEMORY_COUNTER;
每次要申请一块新的direct memory的时候, 它就调用incrementMemoryCounter方法去增加 DIRECT_MEMORY_COUNTER 的值:
最终是通过反射实例化DirectByteBuffer,用的是下面的构造函数:
PlatformDependent0反射实例化代码:
因此netty所分配的直接内存大小,常规的监控手段无法监测,包括arthas、visualvm中的MBean、以及其他所有通过jmx获取直接内存数据的手段。
如果要监控,只能自定义实现,从PlatformDependent入手,网上已有不少资料。
[转帖]直接内存监控不准确,netty玩了什么花?的更多相关文章
- 一文了解 Redis 内存监控和内存消耗
Redis 是一种内存数据库,将数据保存在内存中,读写效率要比传统的将数据保存在磁盘上的数据库要快很多.所以,监控 Redis 的内存消耗并了解 Redis 内存模型对高效并长期稳定使用 Redis ...
- 用python 10min手写一个简易的实时内存监控系统
简易的内存监控系统 本文需要有一定的python和前端基础,如果没基础的,请关注我后续的基础教程系列博客 文章github源地址,还可以看到具体的代码,喜欢请在原链接右上角加个star 腾讯视频链接 ...
- Docker容器内存监控
linux内存监控 要明白docker容器内存是如何计算的,首先要明白linux中内存的相关概念. 使用free命令可以查看当前内存使用情况. [root@localhost ~]$ free tot ...
- iOS微信内存监控
WeTest 导读 目前iOS主流的内存监控工具是Instruments的Allocations,但只能用于开发阶段.本文介绍如何实现离线化的内存监控工具,用于App上线后发现内存问题. FOOM(F ...
- [转]用python 10min手写一个简易的实时内存监控系统
简易的内存监控系统 本文需要有一定的python和前端基础,如果没基础的,请关注我后续的基础教程系列博客 文章github源地址,还可以看到具体的代码,喜欢请在原链接右上角加个star 腾讯视频链接 ...
- docker内存监控与压测
一直运行的docker容器显示内存已经耗尽,并且容器内存耗尽也没出现重启情况,通过后台查看发现进程没有占用多少内存.内存的监控使用的是cadvisor,计算方式也是使用cadvisor的页面计算方式, ...
- 从Container内存监控限制到CPU使用率限制方案
转自:http://blog.csdn.net/Androidlushangderen/article/details/50282593 前言 最近在运维我们部门的hadoop集群时,发现了很多Job ...
- redis内存监控与回收
Redis有自己的内存分配器,当key-value对象被移除时,Redis不会马上向操作系统释放其占用内存.redis之所以这样的设计有两个原因. OS可能会将释放内存交换到虚拟内存,但OS的虚拟内存 ...
- 10min 手写一个内存监控系统
本文的目的在于,尽可能用简单的代码,让大家了解内存监控的原理,及思想.更容易去理解Nagios.Zabbix.Ganglia监控原理,文章最后还有视频教程链接哦,从零敲出来的全过程 思路分为下面几块: ...
- 【性能测试】:JVM内存监控策略的方法,以及监控结果说明
JVM内存监控主要在稳定性压测期间,监控应用服务器内存泄露等问题: [JVM远程监控设置] 1.打开WAS控制台:https://ip:port/ibm/console/login.do 2.进入路径 ...
随机推荐
- mac如何访问同一wifi下的项目-mac-ru-he-fang-wen-tong-yi-wifi-xia-de-xiang-mu
title: mac如何访问同一wifi下的项目 date: 2022-03-28 20:14:06.341 updated: 2022-03-28 21:55:42.53 url: https:// ...
- Ubuntu 20.04 设置时区、配置NTP同步 timesyncd 代替 ntpd
本文的服务器环境为 Ubuntu 20.04 系统,一个拥有 sudo 权限的非 root用户,并开启了防火墙. 基本时间命令 要在 Ubuntu 20.04 系统上查看服务器时间,可以使用 date ...
- 文心一言 VS 讯飞星火 VS chatgpt (43)-- 算法导论5.4 7题
七.为使特征序列长度的下界变得更精确,请说明在 n 次硬币的公平抛掷中,不出现比Ign - 2lglgn 更长的连续正面特征序列的概率小于 1/n. 文心一言: 在 n 次硬币的公平抛掷中,每个硬币正 ...
- Langchain-Chatchat项目:3-Langchain计算器工具Agent思路和实现
本文主要讨论Langchain-Chatchat项目中自定义Agent问答的思路和实现.以"计算器工具"为例,简单理解就是通过LLM识别应该使用的工具类型,然后交给相应的工具( ...
- 第六部分_Shell脚本流程控制语句
流程控制语句 关键词:选择(人生漫漫长路,我该何去何从) 1. 基本语法结构 ㈠ if结构 箴言1:只要正确,就要一直向前冲️ F:表示false,为假 T:表示true,为真 if [ condit ...
- 8种ETL算法汇总大全!看完你就全明白了
摘要:ETL是将业务系统的数据经过抽取.清洗转换之后加载到数据仓库的过程,是构建数据仓库的重要一环,用户从数据源抽取出所需的数据,经过数据清洗,最终按照预先定义好的数据仓库模型,将数据加载到数据仓库中 ...
- 提升软件质量?为什么不试试华为云CodeArts Check
摘要:华为云CodeArts Check代码检查服务为用户提供包括代码风格.通用质量与代码安全风险等在内的检查能力,同时提供问题闭环处理.检查报告等功能,从而一站式完成代码检查作业. 本文分享自华为云 ...
- TypeScript里string和String,真不是仅仅是大小写的区别
摘要:通常来说,string表示原生类型,而String表示对象. 本文分享自华为云社区<TypeScript里string和String的区别>,作者:gentle_zhou . 背景 ...
- Sechunter移动应用隐私合规检测详解
摘要:本文简要介绍Sechunter移动应用隐私合规检测的方法步骤,以及目标检测技术在其中的应用. 本文分享自华为云社区<移动应用隐私合规检测简介及目标检测技术的应用>,作者:wolfre ...
- 下一代APP Store——GPT应用商店GPTs初体验
uploading-image-126879.png 近期,OpenAI宣布GPT应用商店正式上线,目前拥有plus的用户已经可以体验了. OpenAI将GPT应用商店命名为GPTs,这也是之前发布会 ...