1.问题
这段时间最易个图片迁移的工作,涉及60W+图片的迁移,用java写的临时代码,部署到图片服务器上。因为服务器还有其他服务,看日志的同时,也再看迁移的应用对服务器CPU和内存使用的影响。使用top命令猛然发现Mem的used狂涨而free狂降,下面是两个时刻的top情况:
1 2 3 4 5 6 7 8 9 10 11 |
|
2.疑惑
第一想法是内存泄漏了,之前写惯C++代码Windows下碰到过一次明显的内存泄漏,情况和这个完全类似。
但是这个是java代码,java想写出内存泄漏的代码不容易。
3.原因
问了个老鸟,原因是Linux的内存管理和Windows不一样。在Linux下,无论物理内存有多大都将其充份利用,会将应用程序调用过的硬盘数据保留在内存,利用内存读写的高速特性来提高Linux系统的数据访问性能。
3.1 linux中内存是如何使用
当有应用需要读写磁盘数据时,由系统把相关数据从磁盘读取到内存,如果物理内存不够,则把内存中的部分数据导入到磁盘,从而把磁盘的部分空间当作虚拟内存来使用,也称为Swap。如果给所有应用分配足够内存后,物理内存还有剩余,linux会尽量再利用这些空闲内存,以提高整体I/O效率,其方法是把这部分剩余内存再划分为cache及buffer两部分加以利用。
从磁盘读取到内存的数据在被相关应用程序读取后,如果有剩余内存,则这部分数据会存入cache,以备第2次读取时,避免重新读取磁盘。当一个应用程序在内存中修改过数据后,因为写入磁盘速度相对较低,在有空闲内存的情况下,这些数据先存入buffer,在以后某个时间再写入磁盘,从而应用程序可以继续后面的操作,而不必等待这些数据写入磁盘的操作完成。
如果在某个时刻,系统需要更多的内存,则会把cache部分擦除,并把buffer中的内容写入磁盘,从而把这两部分内存释放给系统使用,这样再次读取cache中的内容时,就需要重新从磁盘读取了。
通过以上分析可以得知,Mem中的空闲物理内存(free)不多,不一定表示系统运行状态很差,因为内存的cache及buffer部分可以随时被重用,在某种意义上,这两部分内存也可以看作是额外的空闲内存。
4.Linux和Windows内存管理的差异
无论物理内存有多大,Linux都将其充份利用,将一些程序调用过的硬盘数据读入内存,利用内存读写的高速特性来提高Linux系统的数据访问性能。
而Windows 是只在需要内存时,才为应用程序分配内存,并不能充分利用大容量的内存空间。
换句话说,每增加一些物理内存,Linux 都将能充分利用起来,发挥了硬件投资带来的好处,而Windows只将其做为摆设,即使增加8GB甚至更大。
5.什么是Linux的cache,buffers,Swap
Cached表示page cache大小,Buffers表示内存中块I/O缓冲(buffer cache)的大小。通常而言,Cached很关键,Buffers则影响不大。
简单来说,磁盘的操作有逻辑级(文件系统)和物理级(磁盘块),page cache对应的就是用来缓存逻辑级数据,buffer cache用来缓存物理级数据。
假设我们通过文件系统操作文件,那么文件将被缓存到Page Cache,如果需要刷新文件的时候,page cache将交给buffer cache去完成,因为buffer cache就是缓存磁盘块的。 也就是说,直接去操作文件,那就是page cache区缓存,用dd等命令直接操作磁盘块,就是buffer cache缓存的东西。
5.1 buffer
buffer是作为buffer cache的内存,是块设备的读写缓冲区。
buffer cache也叫块缓冲,由物理内存分配,是对物理磁盘上的一个磁盘块(磁盘的组织单位)进行的缓冲。
设立buffer cache的目的是为在程序多次访问同一磁盘块时,减少访问时间。系统将磁盘块首先读入buffer cache,如果cache空间不够时,会通过一定的策略将一些过时或多次未被访问的buffer cache清空。程序在下一次访问磁盘时首先查看是否在buffer cache找到所需块,命中可减少访问磁盘时间,不命中时需重新读入buffer cache。
对buffer cache 的写分为两种,一是直接写,这是程序在写buffer cache后也写磁盘,要读时从buffer cache 上读,二是后台写,程序在写完buffer cache 后并不立即写磁盘,因为有可能程序在很短时间内又需要写文件,如果直接写,就需多次写磁盘了,这样效率很低,而是过一段时间后由后台写(批量写),减少了多次访磁盘的时间。
buffer cache 是由物理内存分配,linux系统为提高内存使用率,会将空闲内存全分给buffer cache ,当其他程序需要更多内存时,系统会减少cahce大小。
5.2 cache
cache是page cache的内存, 文件系统的cache。
page cache也叫页缓冲或文件缓冲,文件读取是由外存上不连续的几个磁盘块,到buffer cache,然后组成page cache,然后供给应用程序。
page cache在linux读写文件时,它用于缓存文件的逻辑内容,从而加快对磁盘上映像和数据的访问。具体说是加速对文件内容的访问,buffer cache缓存文件的具体内容——物理磁盘上的磁盘块,这是加速对磁盘的访问。
5.3 Swap
swap space交换空间,是虚拟内存的表现形式。系统为了应付一些需要大量内存的应用,而将磁盘上的空间做内存使用,当物理内存不够用时,将其中一些暂时不需的数据交换到交换空间。
做虚拟内存的好处是让进程以为好像可以访问整个系统物理内存。因为在一个进程访问数据时,其他进程的数据会被交换到交换空间中。
6.Linux内存常用命令
6.1 top
1 2 3 4 5 6 7 8 9 |
|
字段的意义如下:
1 2 3 4 5 6 7 8 9 10 11 12 |
|
top命令提供了额外的输入,常用的命令包括(注意是大写):
1 2 3 |
|
6.2 free
1 2 3 4 5 |
|
-m表示单位为M,可以使用-g表示单位为G,默认为K。 -/+ buffers/cache表示物理内存的缓存统计,Used为4506,即实际使用的buffers与cache 总量,也是实际使用的内存总量;Free为3352, 即未被使用的buffers与cache和未被分配的内存之和,这就是系统当前实际可用内存。
Swap表示硬盘上交换分区的使用情况。只有mem被当前进程实际占用完,即没有了buffers和cache时,才会使用到swap。
注意一下几个关系: Free(-/+ buffers/cache行)= Free(Mem)+buffers(Mem)+Cached(Mem)
Used(Mem) = Used(-/+ buffers/cache)+ buffers(Mem) + Cached(Mem)
total(Mem) = used(-/+ buffers/cache) + free(-/+ buffers/cache)
从应用程序角度来看,对于应用程序来说,buffers/cached 是等于可用的,因为buffer/cached是为了提高文件读取的性能,当应用程序需在用到内存的时候,buffer/cached会很快地被回收。所以从应用程序的角度来说,可用内存=系统free memory+buffers+cached.
6.3 /proc/meminfo
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 |
|
其中的MemTotal, MemFree, Buffers, Cached, SwapTotal, SwapFree和free命令中的值对应起来。
Cached is the size of the page cache。 Buffers is the size of in-memory block I/O buffer。
6.4 vmstat
vmstat -s显示内存使用的统计信息
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 |
|