最近,我开始监控我们一直在开发的Node.js应用程序。过了一段时间,我发现它的内存占用增长缓慢,3天就增长了20%。内存使用量是在以下Node.js代码中测量的。constos=require("os");consttotal=os.totalmem();constfree=os.freemem();const使用量=((免费-总计)/总计)*100;因此,它们基本上来自操作系统,在本例中是Docker上的AlpineLinux。幸运的是,我还记录了应用程序进程的内存使用情况,但它们并没有增加。那么为什么操作系统内存使用量会增加呢?Bufferandcachememory我使用top命令Shift+m??(按内存使用排序),将长时间运行的服务器上的进程与新部署的服务器进行比较。双方的过程几乎相同。唯一的区别是缓冲区和缓存的Mem从长远来看是很高的。经过一些研究或谷歌搜索后,我得出的结论是这不是问题所在。当应用程序进程请求更多内存时,大多数缓冲区和缓存的Mem都会被丢弃。其实free-m命令提供了一行used,free有buffer和cache的考虑。$free-mtotalusedfreesharedbufferscachedMem:3950285366518312188-/+buffers/cache:843866Swap:189601896那么,它们到底是什么?根据手册/proc/meminfo,这是一个伪文件和free、top和朋友的数据源:Buffers%lu原始磁盘块的相对临时存储,不应变得非常大(20MB左右)。缓存%lu从磁盘读取的文件的内存缓存(页面缓存)。不包括SwapCached。我仍然不确定Buffers究竟包含什么,但它包含文件的元数据等,而且它的大小相对较小。Cached包含缓存的文件内容,称为页面缓存。操作系统保留页面缓存,RAM有足够的可用空间。这就是为什么即使进程没有泄漏内存,内存使用量也在增加。如果您有兴趣,请问/proc/meminfo输出中的Buffers和Cached列有什么区别?Quora上有关于Buffers和Cached的更多细节。AvailableMemory那么,我们应该使用free+buffers+cached吗?/proc/meminfo有一个更好的指标,称为MemAvailable。MemAvailable%lu(自Linux3.14起)估计有多少内存可用于启动新应用程序,无需交换。$cat/proc/meminfoMemTotal:4045572kBMemFree:3753648kBMemAvailable:3684028kBBuffers:13048kached...3BCached背景在Linux内核的提交中有很好的解释,但本质上它排除了不可释放的页面缓存并包括可回收的平板内存.Linuxv4.12-rc2中的当前实现看起来仍然非常相似。free-m对可用列有一些实现。例如在Boot2Docker上:$free-mtotalusedfreesharedbuff/cacheavailableMem:39505936651832263597Swap:189601896它也可以通过--mem-available标志在AWSCloudWatch指标上获得。Docker的一些背景我的另一个问题是“这些指标在Docker中是否相同?”。在深入探讨之前,让我们先看看docker是如何工作的。根据DockerOverview:UnderlyingTechnologies,Docker容器中的进程直接在其主机操作系统中运行,无需任何虚拟化,但由于这些Linux内核特性,它们与主机操作系统和其他容器有效隔离:命名空间:隔离PID、主机名、用户ID,网络访问、IPC等cgroups:限制资源使用UnionFS:隔离文件系统由于命名空间的原因,pscommand除了列出宿主操作系统中的其他进程外,还列出了Docker容器的进程,它无法列出宿主操作系统或码头集装箱。其他容器的进程。默认情况下,Docker容器没有资源限制。所以,如果你在主机上运行一个容器,并且你不限制容器的资源使用,这是我的情况,容器的“可用内存”与主机操作系统的“可用内存”相同.Docker容器上的内存指标如果您想从容器外部监控Docker容器的内存使用情况,这很容易。您可以使用dockerstats.$dockerstatsCONTAINERCPU%MEMUSAGE/LIMITMEM%NETI/OBLOCKI/OPIDSfc015f31d9d10.00%220KiB/3.858GiB0.01%1.3kB/0B0B/0B2但是如果你想得到,或者要获得更详细的指标,它会变得复杂。Linux容器内的内存详细说明了困难。/proc/meminfo和sysinfo,由Node.js使用os.totalmem()和os.freemem()使用,不是孤立的,如果您在Docker容器中使用top等常用实用程序,您将获得主机操作系统的无索引。要获取特定于Docker容器的指标,您可以在/sys/fs/cgroup/memory/中找到它们。但是,它们并未标准化为Linux容器内的内存。$cat/sys/fs/cgroup/memory/memory.usage_in_bytes303104$cat/sys/fs/cgroup/memory/memory.limit_in_bytes9223372036854771712memory.limit_in_bytes如果没有限制则返回一个非常大的数字。在这种情况下,您可以使用/proc/meminfo或使用它的命令找到主机操作系统的总内存。结论这是一段比我最初想象的要长的旅程。我的要点是:可用内存>可用内存即:允许内存使用>可用内存MemAvailable当Docker容器中的MemAvailable进程直接在主机操作系统中运行时确切知道你在测量什么,尤其是在Docker容器中
