内存那些事

内存那些事

linux中的free -m可以查看当前的内存使用情况

[yejianfeng@iZ23fsd ~]$ free -m
             total       used       free     shared    buffers     cached
Mem:          7869       7737        132          0        489       4419
-/+ buffers/cache:       2828       5040
Swap:            0          0          0

这里会让人奇怪的就是为什么除了used和free,还有个buffers,cached的使用。

buffer是系统把将要写入磁盘的数据先存放起来,然后一次性写入磁盘。cache则是将要从磁盘读取的数据先缓存起来,等待下次读取或者一次性读取。对于人来说,我们认为这一部分的缓存是已经使用了的,但是对于操作系统来说,这一部分的内存是“没有使用”的。因为这部分的内存随时可以释放。所以这部分意思是:

total: 总共有的内存
used: 已经使用的内存数(人的角度看的,既: 进程实际使用的内存+buffers+cached)
free: 空闲内存(人的角度看的)
shared: 进程共享内存
buffers: 操作系统预留的为进程IO读取使用的缓冲区
cached: 操作系统为最近打开的文件进行的缓存
-/+ buffer: 操作系统角度看的实际使用的内存数

虚拟内存和物理内存

我们在使用top命令看进程的时候,会看到下面的几个东西:
PID USER PR NI VIRT RES SHR S %CPU %MEM TIME+ COMMAND
2344 vagrant 20 0 98276 2020 1052 S 0.0 0.4 0:00.49 sshd
2345 vagrant 20 0 105m 1868 1488 S 0.0 0.4 0:00.08 bash
1136 nginx 20 0 45676 1740 440 S 0.0 0.4 0:00.00 nginx
1022 root 20 0 308m 1604 820 S 0.0 0.3 0:05.10 VBoxService

这里会看到几个属性:

VIRT RES SHR

这三个值都是表示这个进程的内存使用状况,其中的VIRT指的是进程使用的虚拟内存,RES指的是进程使用的物理内存,SHR指的是进程使用的共享内存。

关于虚拟内存和物理内存

打一个形象的比喻,一列车从北京到上海,有1500公里,我们应该要铺设1500公里的铁轨。但是,我们想了个取巧的办法,我们实际只需要三公里的铁轨,当列车快行驶完成铁轨的时候,我们把已经走过的铁轨铺设到列车前方,这样,列车就可以使用3公里的铁轨就进行行驶了。在这个例子中,虚拟内存就是代表1500公里,而物理内存就是代表3公里。我们一个进程在操作系统中实际使用的物理内存会远远小于分配的虚拟内存。比如一个php-fpm进程实际使用大概20-30M的物理内存,而你看他的虚拟内存,大概会有150M左右。

我们机器的内存是恒定的,那么这些大出来的虚拟内存是存放在哪里的呢?当然是硬盘。对于计算机来说,处理信息查找会先在L1缓存中找需要的数据,如果没有,在L2缓存中查找,如果还没有,在内存中查找,如果还没有,先去硬盘中的虚拟内存区域找,如果还没有,再去硬盘中找,如果都没有,就跳过这次处理(可能程序崩溃或者蓝屏)。

引入虚拟内存技术的好处是程序不需要再管物理内存中哪块空闲,哪块有用了。这些全部交给操作系统来管理,再程序面前,就像是有一块连续的,未使用的内存空间一样。当程序启动的时候,系统会为每个程序分配一定的内存空间。在32bit的机器上,这个内存空间的上限是4G(0x00000000 - 0xffffffff),而其中分为两个部分,用户态使用的内存,内核态使用的内存。其中3G(0x00000000 - 0xbfffffff)是用户态可以使用的内存,而1G(0xc0000000 - 0xffffffff)是内核态使用的内存。所以在许多windows的x86机器上,安装的内存条大小最多是4G的,因为安装再大的内存,可以使用的内存大小也是有限制的。

而对于64bit的机器,这个内存是没有4G的上限的,理论上可以支持2^64的大小的内存地址的。所以一般服务器上对内存的最大上限都不做限制,这点可以使用ulimit -a 得到验证:

[vagrant@localhost /]$ ulimit -a
core file size          (blocks, -c) 0
data seg size           (kbytes, -d) unlimited
scheduling priority             (-e) 0
file size               (blocks, -f) unlimited
pending signals                 (-i) 3528
max locked memory       (kbytes, -l) 64
max memory size         (kbytes, -m) unlimited
open files                      (-n) 1024
pipe size            (512 bytes, -p) 8
POSIX message queues     (bytes, -q) 819200
real-time priority              (-r) 0
stack size              (kbytes, -s) 10240
cpu time               (seconds, -t) unlimited
max user processes              (-u) 1024
virtual memory          (kbytes, -v) unlimited
file locks                      (-x) unlimited

对于虚拟内存和物理内存,这里其实最复杂的是他们的映射机制。这个机制是操作系统内核要实现的东东,这里就不继续看下去了。

共享内存

很多进程可能需要加载动态库,比如libc,而这些动态库就可以默认存放到共享内存中,而不用每个进程都进行加载了。还有进程也可以存放数据到共享内存中,这样他们的子进程就可以到共享内存中进行操作,比如php的shmop系列的命令就是操作共享内存的。

好了,这里有个奇怪的现象,明明top中在SHR中看到很多共享内存,为什么free -m中的shared为0呢?--实际上free命令中的shared已经被废弃了,没有进行计算了。具体参考man

时间: 2024-11-02 10:28:57

内存那些事的相关文章

内存坏了电脑会有哪些反应

  电脑内存损坏这种情况是广大win7系统和xp系统用户时有发生的,而内存坏了后,电脑系统出现什么情况呢?相信大家对此并不是十分的清楚,内存出问题出,电脑的反应也是多种多样的,系统之家就为大家罗列了下几种情况: 1.内存插上后主板报警.这种情况是无法开机的(上不了xp系统).这是属于内存坏了情况. 2.在电脑win7系统或xp系统开机后出现000x000000蓝屏的类似情况,这种情况是属于内存频率和主板总线出现的问题,可能是主板不支持该内存的频率. 3.电脑开机xp系统正常运行,但是在运行大型运

flex3:利用itemRenderer创建在线书店的图书信息显示页面

第一部分:预备知识----认识itemRenderer 我们经常用itemRenderer,使用List,DataGrid,TileList等组件时经常动不动就来个itemRenderder.虽然很熟悉了,但是我打算今天还是再好好认识一下它. 使用itemRenderer有两点需要注意: 1,对于flex框架,使用itemRenderer很件很耗费内存的事,如果可以避免尽量不要用. 2,一个误会 假设我有一个List组件,与他绑定的数据有1000条,现在我要渲染这个List.是不是要创建1000

Node.js中的事件驱动编程详解_node.js

在传统程编程模里,I/O操作就像一个普通的本地函数调用:在函数执行完之前程序被堵塞,无法继续运行.堵塞I/O起源于早先的时间片模型,这种模型下每个进程就像一个独立的人,目的是将每个人区分开,而且每个人在同一时刻通常只能做一件事,必须等待前面的事做完才能决定下一件事做什么.但是这种在计算机网络和Internet上被广泛使用的"一个用户,一个进程"的模型伸缩性很差.管理多个进程时,会耗费很多内存,上下文切换也会占用大量资源,这些对操作系统是个很大的负担,而且随着进程数的递增,会导致系统性能

SQL Server误区30日谈 第19天 Truncate表的操作不会被记录到日志_MsSql

误区 #19:Truncate表的操作不会被记录到日志 错误 在用户表中的操作都会被记录到日志.在SQL Server中唯一不会被记录到日志的操作是TempDB中的行版本控制. Truncate Table语句会将整个表中的所有数据删除.但删除的方式并不是一行一行的删除,而是将组成表的数据页释放,将组成表的相关页释放的操作交给一个后台的线程进行队列处理的过程被称为deferred-drop.使用后台线程处理deferred-drop的好处是这个操作不会使得其所在的事务需要执行很长时间,因此也就不

SQL Server误区30日谈 第19天 Truncate表的操作不会被记录到日志

误区 #19:Truncate表的操作不会被记录到日志 错误 在用户表中的操作都会被记录到日志.在SQL Server中唯一不会被记录到日志的操作是TempDB中的行版本控制. Truncate Table语句会将整个表中的所有数据删除.但删除的方式并不是一行一行的删除,而是将组成表的数据页释放,将组成表的相关页释放的操作交给一个后台的线程进行队列处理的过程被称为deferred-drop.使用后台线程处理deferred-drop的好处是这个操作不会使得其所在的事务需要执行很长时间,因此也就不

提高大容量内存性能,这是你内存大最应该做的事。

现在很多人的内存都有8G.16G甚至32G之类的超大内存,这是我们最应该考虑的是提高大容量内存性能 ,也就是让你的内存能发挥最大的功效.而不是有着大内存且没感觉到比以前低内存快多少.发生这种事就是你电脑设置得不够好. 1 根据我所知道的,可以改3个地方,下面就跟着我一一来修改吧. 3个地方都是在注册表哦,所以我们要先进入注册表编辑器,运行输入:regedit就进入了. 2 第一个要改的是LargeSystemCache的值 LargeSystemCache默认值为4,也就是4M,这个值是系统缓存

Android中内存优化的那些事 - 一个有关图片的优化记录

客服群里叫喊着:这个用户图片不显示了,那个用户图片也不显示了.我拿着手上一切正常的测试机,what the hell-- 默默地打开bugly.   满园春色关不住,遍地内存溢出来!是的,又闯祸了! 内存问题永远是既陌生又熟悉的话题,而且大多数都发生在一个叫作用户家的手机上.安卓系统本身不断的在优化,三方框架也逐渐成熟,外加手机厂商的大内存加持,似乎内存问题变得少见,但还是不能忽视. 借着这次修复内存问题的记录,分享一些"自以为"的解决思路,仅供参考.ok,let's go! 修复问题

iOS开发那些事--性能优化–内存泄露问题的解决

内存泄漏问题的解决 内存泄漏(Memory Leaks)是当一个对象或变量在使用完成后没有释放掉,这个对象一直占有着这块内存,直到应用停止.如果这种对象过多内存就会耗尽,其它的应用就无法运行.这个问题在C++.C和Objective-C的MRR中是比较普遍的问题. 在Objective-C中释放对象的内存是发送release和autorelease消息,它们都是可以将引用计数减1,当为引用计数为0时候,release消息会使对象立刻释放,autorelease消息会使对象放入内存释放池中延迟释放

IOS中内存管理那些事_IOS

Objective-C 和 Swift 语言的内存管理方式都是基于引用计数「Reference Counting」的,引用计数是一个简单而有效管理对象生命周期的方式.引用计数分为手动引用计数「ARC: AutomaticReference Counting」和自动引用计数「MRC: Manual Reference Counting」,现在都是用 ARC 了,但是我们还是很有必要了解 MRC. 1. 引用计数的原理是什么? 当我们创建一个新对象时,他的引用计数为1: 当有一个新的指针指向这个对象