前几天我发了一篇文章:在 4GB 物理内存的机器上,申请 8G 内存会怎么样?,但是当时写的比较匆忙,文章中只考虑关闭 swap 的情况,没有提及开启 swap 的情况,有读者希望我补充这部分内容。
这篇文章其实之前发过,但是最近有位读者跟我反馈,我文章中的实验在 64 位操作系统、2 G 物理内存的场景,申请 8G 内存是没问题的,而他也是这个环境,为什么他就无法申请成功呢?
使用 malloc 函数申请内存原理 : " 堆内存 " 动态分配 的 系统调用 过程 ;
cat /proc/meminfo 各字段详解 /proc/meminfo是了解Linux系统内存使用状况的主要接口,我们最常用的”free”、”vmstat”等命令就是通过它获取数据的 ,/proc/meminfo所包含的信息比”free”等命令要丰富得多,因此需要了解这些字段的含义。 / $ cat /proc/meminfo MemTotal: 877368 kB :所有可用RAM大小(即物理内存减去一些预留位和内核的二进制代码大小)(HighTotal + LowTotal),
以交友平台用户中心的user表为例,单表数据规模达到千万级别时,你可能会发现使用用户筛选功能查询用户变得非常非常慢,明明查询命中了索引,但是,部分查询还是很慢,这时候,我们就需要考虑拆分这张user表了。
对于内存监控,在top里我们要时刻监控第五行swap交换分区的used,如果这个数值在不断的变化,表示内核在不断进行内存和swap的数据交换,说明内存真的不够用了。
其中,第一个问题「在 4GB 物理内存的机器上,申请 8G 内存会怎么样?」存在比较大的争议,有人说会申请失败,有的人说可以申请成功。
本文主要分析 Linux 系统内存统计的一些指标以及进程角度内存使用监控的一些方法。
负载均衡(uptime) load average: 0.00, 0.00, 0.00
某次遇到一个客户尝试用 Java (其实跟具体用什么语言没关系)申请使用 4G 的内存申请,机器(ECS)总内存是 8G,free 的内存也超过 4G,按道理是 OK 的,但总是直接 OOM。
top命令是Linux下常用的性能分析工具,能够实时显示系统中各个进程的资源占用状况,类似于Windows的任务管理器
使用ps命令查看进程的内存使用情况时,有3列输出,分别是%MEM、VSZ和RSS,其中VSZ全称为Virtual Memory Size,RSS全称为Resident Set Size,而MEM则是RSS占全部内存的百分比。
内存是计算机中必不可少的资源,因为 CPU 只能直接读取内存中的数据,所以当 CPU 需要读取外部设备(如硬盘)的数据时,必须先把数据加载到内存中。
通过获取Linux中的 /proc/stat 文件中的内容可以获取系统内存的详细信息:
在启动一个Springboot工程时,抛出一项“Cannot allocate memory”异常,很明显,是因为内存分配原因导致的OOM异常导致JVM宕掉。跟随log,查看JVM hs_err_pid24442.log文件。
爱可生交付服务部团队北京 DBA,主要负责处理 MySQL 的 troubleshooting 和我司自研数据库自动化管理平台 DMP 的日常运维问题,对数据库及周边技术有浓厚的学习兴趣,喜欢看书,追求技术。
最近一台 CentOS 服务器,发现内存无端损失了许多,free 和 ps 统计的结果相差十几个G,非常奇怪,后来Google了许久才搞明白。
之前写了两篇详细分析 Linux 内存管理的文章,读者好评如潮。但由于是分开两篇来写,而这两篇内容其实是有很强关联的,有读者反馈没有看到另一篇读起来不够不连贯,为方便阅读这次特意把两篇整合在一起,看这一篇就够了!
在实际的软件开发过程中,内存问题常常是耗费大量时间进行分析的挑战之一。为了更有效地定位和解决与内存相关的难题,一系列辅助工具应运而生,其中备受赞誉的Valgrind工具便是其中之一。事实上,笔者本人曾利用Valgrind工具成功地发现并解决了一个隐藏在软件中的bug,这充分体现了工具在开发过程中的重要性。
问题背景:一次启动本地应用,两分钟过后自动退出,通过日志并未发现任何异常状况,莫名其妙的应用就自动被杀掉了;
C/C++程序为编译后的二进制文件,运行时载入内存,运行时内存分布由代码段、初始化数据段、未初始化数据段、堆和栈构成,如果程序使用了内存映射文件(比如共享库、共享文件),那么包含映射段。Linux环境程序典型的内存布局如图1-5所示。
认为的先规划成两部分,用户的物理内存和内核的物理内存,专项专用,内核有方法去占用用户的内存,但是规定两部分内存是专用的,内核只使用自己的物理内存。
Linux开发一般会遇到“/proc/sys/vm/overcommit_memory”,即文件/etc/sysctl.conf中的vm.overcommit_memory,Overcommit的意思如同其字面意思,即进程可申请超出可用内存大小的内存(对进程而言实为虚拟内存,一个进程占用的虚拟内存空间通常比物理空间要大,甚至可能大许多)。overcommit_memory有三种取值(注:overcommit_memory并不控制OOM,是否开启OOM由panic_on_oom控制):
Linux内核给每个进程都提供了一个独立的虚拟地址空间,并且这个地址空间是连续的。Linux的空间又分为内核空间和用户空间,在32位中,内核空间占1G,用户空间占3G;而在64位中,内核空间和用户空间各占128T。如图3-24所示。
大致意思就是,他看了一个面经,说虚拟内存是 2G 大小,然后他看了我的图解系统 PDF 里说虚拟内存是 4G,然后他就懵逼了。
Linux内核中采用了一种同时适用于32位和64位系统的内存分页模型,对于32位系统来说,两级页表足够用了,而在x86_64系统中,用到了四级页表。四级页表分别为:
这些参数主要是用来调整virtual memory子系统的行为以及数据的写出(从RAM到ROM)。 这些节点(参数)的默认值和初始化的过程大部分都可以在mm/swap.c中找到。 目前,/proc/sys/vm目录下有下面这些节点:
a) 如果当前连续内存块足够 realloc 的话,只是将 p 所指向的空间扩大,并返回 p 的指针地址。这个时候 q 和 p 指向的地址是一样的
在使用 docker 运行容器时,默认的情况下,docker没有对容器进行硬件资源的限制,当一台主机上运行几百个容器,这些容器虽然互相隔离,但是底层却使用着相同的 CPU、内存和磁盘资源。如果不对容器使用的资源进行限制,那么容器之间会互相影响,小的来说会导致容器资源使用不公平;大的来说,可能会导致主机和集群资源耗尽,服务完全不可用。
无论是 windows 系统还是 linux 操作系统,在硬盘上都有一块虚拟内存的空间。 无论你使用的是哪个系统,都存在一个问题,那就是到底虚拟内存的空间需要多大呢?虚拟内存又是什么呢? 本文就来详细介绍一下。
平常处理服务器的问题遇到的最多的是负载高了,内存高了,io高了等问题,这里最明显的表现就是相关的监控指标了,对于诊断这种问题起到事半功倍的效果。
在 Linux 下 free 命令可以看出系统当前内存状况,附上 -k , -m , -g 可以分别输出对应单位的内存状况:
之前文章《Linux服务器性能评估与优化(一)》太长,阅读不方便,因此拆分成系列博文:
当前时间(date)、系统已运行时间(last reboot)、当前登录用户的数量(who )、最近5、10、15分钟内的平均负载
内核使用cgroup对进程进行分组,并限制进程资源和对进程进行跟踪。内核通过名为cgroupfs类型的虚拟文件系统来提供cgroup功能接口。cgroup有如下2个概念:
很明显,安装OB时要求服务器可用内存至少 8G,不达标就无法安装。为了凑这3台10G内存的服务器我已经费了不少劲了,free -m 输出中 free 不是有 9G 吗,为什么还报错?
我们组的实时数仓项目(二期:Flink SQL指标计算)进入上线阶段。所以,最近的推文我会持续更新一些线上问题排查的实战经验和思路,并尽量针对一类相似或者关联问题所涉及的关键点进行总结,抽出一些方法论分享给大家,感谢支持^^
processor : 0 #每个逻辑cpu 唯一编号0-N,编号到N则说明有N个逻辑CPU
前面提到了虚拟内存需要映射物理内存才能使用,这个映射关系被保存在内存中的页表(Page Table)。现代 CPU 架构中一般有 TLB (Translation Lookaside Buffer,翻译后备缓冲,也称为页表寄存器缓冲)存在,在里面保存了经常使用的页表映射项。TLB 的大小有限,一般 TLB 如果只能容纳小于 100 个页表映射项。 我们能让程序的虚拟内存对应的页表映射项都处于 TLB 中,那么能大大提升程序性能,这就要尽量减少页表映射项的个数:页表项个数 = 程序所需内存大小 / 页大小。我们要么缩小程序所需内存,要么增大页大小。我们一般会考虑增加页大小,这就大页分配的由来,JVM 对于堆内存分配也支持大页分配,用于优化大堆内存的分配。那么 Linux 环境中有哪些大页分配的方式呢?
top命令是Linux下常用的性能分析工具,能够实时显示系统状况,比如cpu、内存的使用等。以下详细介绍 top 命令。
众所周知,程序需要加载到物理内存才能运行,多核时代会出现多个进程同时操作同一物理地址的情况,进而造成混乱和程序崩溃。计算机当中很多问题的解决都是通过引入中间层,为解决物理内存使用问题,虚拟内存作为中间层进入了操作系统,从此,程序不在直接操作物理内存,只能看到虚拟内存,通过虚拟内存,非常优雅的将进程环境隔离开来,每个进程都拥有自己独立的虚拟地址空间,且所有进程地址空间范围完全一致,也给编程带来了很大的便利,同时也提高了物理内存的使用率,可同时运行更多的进程。
/proc/meminfo是了解Linux系统内存使用状况的主要接口,我们最常用的”free”、”vmstat”等命令就是通过它获取数据的 ,/proc/meminfo所包含的信息比”free”等命令要丰富得多,然而真正理解它并不容易,比如我们知道”Cached”统计的是文件缓存页,manpage上说是“In-memory cache for files read from the disk (the page cache)”,那为什么它不等于[Active(file)+Inactive(file)]?AnonHugePages与AnonPages、HugePages_Total有什么联系和区别?很多细节在手册中并没有讲清楚,本文对此做了一点探究。
虚拟地址空间(Virtual Address Space)是每一个程序被加载运行起来后,操作系统为进程分配的虚拟内存,它为每个进程提供了一个假象,即每个进程都在独占地使用主存。
解释已经很清楚了,主要有以下几个关键点: 1. 1 代表系统所保留空闲内存的最低限
free命令用于显示系统内存使用情况,包括物理内存(Physical Memory)、虚拟内存(Swap Memory)、共享内存(Shared Memory)以及内核使用的缓冲(Buffers)与缓存(Cached)大小。在Linux系统监控的工具中,free命令是最经常使用的命令之一。
第一行:系统时间 21:53:29、运行时间:up 8 day、当前连接数:1 user 、 负载均衡(uptime): load average:0.052,0.32,0.35 average后面的三个数分别是1分钟、5分钟、15分钟的负载情况。 load average数据是每隔5秒钟检查一次活跃的进程数,然后按特定算法计算出的数值。如果这个数除以逻辑CPU的数量,结果高于5的时候就表明系统在超负荷运转了 第二行:Tasks — 任务(进程) 总进程:115 total、运行;1 running、休眠:111 sleep 、停止: 0 stopped 、僵尸进程:1 zombie 第三行:CPU状态
想写这个系列很久了,对自己也是个总结与提高。原来在学JAVA时,那些JAVA入门书籍会告诉你一些规律还有法则,但是用的时候我们一般很难想起来,因为我们用的少并且不知道为什么。知其所以然方能印象深刻并学以致用。
领取专属 10元无门槛券
手把手带您无忧上云