内存管理

虚拟内存 --- 物理内存

应用程序申请虚拟内存 --- RAM + SWAP (真正主板上的设备)

他们之间有一张映射表 page table 页表

PTE: 页表条目 虚拟内存和物理内存的映射关系

每一条的条目叫PTE

cpu MMU 内存管理单元

虚拟内存与物理内存之间做映射的管理单元

TLB 大页 给PTE提供缓存, 从内存中分配, 从内存中分配一段区域来缓存PTE记录

下次打开从缓存TLB里面调用,不需要通过mmu重新分配

sysctl -a | grep huge

过滤大页选项

cat /proc/meminfo

查看内存内容

大页是一段连续的地址空间,一段分配,大页不使用,空间也被占用了。默认情况系统不使用大页,大页用来记录PTE的缓存

[root@workstation ~]# lab memtuning-paging start

实验

[root@servera ~]# vi /etc/sysctl.conf
[root@servera ~]# sysctl -p
vm.swappiness = 15
vm.nr_hugepages = 100
[root@servera ~]#
[root@servera ~]#
[root@servera ~]#
[root@servera ~]# cat /proc/meminfo | grep -i huge
AnonHugePages: 16384 kB
ShmemHugePages: 0 kB
HugePages_Total: 100
HugePages_Free: 100
HugePages_Rsvd: 0
HugePages_Surp: 0
Hugepagesize: 2048 kB
Hugetlb: 204800 kB

申请100M的大页

[root@servera ~]# bigmem  -H 100M
Process PID: 5928
Allocating 100 MiB of huge pages (50 pages)
Assuming 2 MiB huge pages...
Done [root@servera ~]# cat /proc/meminfo | grep -i huge
AnonHugePages: 16384 kB
ShmemHugePages: 0 kB
HugePages_Total: 100
HugePages_Free: 50
HugePages_Rsvd: 0

vm.nr_hugepages = 100

大页数

一个大页2048k

大页一共大小 200M

分配大页让cpu更节省资源

大页很难设置好,所以

透明大页

当你需要大页时,系统动态分配大页

[root@servera transparent_hugepage]# cat enabled
[always] madvise never
[root@servera transparent_hugepage]# pwd
/sys/kernel/mm/transparent_hugepage
[root@servera transparent_hugepage]# [root@servera transparent_hugepage]# echo never > enabled
[root@servera transparent_hugepage]# pwd
/sys/kernel/mm/transparent_hugepage
[root@servera transparent_hugepage]# cat enabled
always madvise [never]
[root@servera transparent_hugepage]#

madvise 触发式 (在特殊情况下)

THP(透明大页)在某些场景会出现异常 Oracle MongoDB Redis 可能导致延迟和内存使用问题

Oracle MongoDB Redis

大内存使用,内存消耗大户

数据库调优首先关闭透明大页

华为的虚拟化用到了透明大页和NUMA



大页的设置参照这个公式比较好

内核参数

hugepages=整数

hugetlbfs

如果你的应用程序需要调用大页那你就得配置hugetlbfs (应用程序包含mmap调用)

那你就得需要配置虚拟文件系统

有没有你都把它挂上就好了

nodev hugetlbfs /hugetlbfs defaults 0 0

mkdir /my-hugepages

mount -t hugetlbfs none /my-hugepages

这个设备名去 /proc/filesystems里面看

追踪可以查看到命令里的mmap

strace 追踪

-c 统计

[root@foundation0 ~]# strace -c cp -r /etc/ /tmp
% time seconds usecs/call calls errors syscall
------ ----------- ----------- --------- --------- ----------------
19.07 0.191608 59 3216 13 openat
18.06 0.181443 62 2917 read
13.53 0.135940 53 2527 lstat
13.16 0.132202 41 3206 close
12.23 0.122903 38 3203 fstat
7.83 0.078694 51 1526 write
5.08 0.051012 37 1374 fadvise64
3.62 0.036399 42 864 getdents64
3.49 0.035071 81 432 mkdir
2.39 0.023991 83 289 symlinkat
1.19 0.011930 41 289 readlink
0.16 0.001571 43 36 mmap
0.07 0.000675 42 16 mprotect
0.03 0.000325 36 9 1 lseek
0.02 0.000207 103 2 statfs
0.01 0.000112 22 5 brk
0.01 0.000090 45 2 munmap
0.01 0.000073 36 2 umask
0.01 0.000070 70 1 rt_sigprocmask
0.01 0.000070 70 1 prlimit64
0.01 0.000055 55 1 futex
0.01 0.000052 26 2 rt_sigaction
0.00 0.000048 48 1 1 newfstatat
0.00 0.000046 23 2 1 access
0.00 0.000040 40 1 stat
0.00 0.000038 38 1 sysinfo
0.00 0.000037 37 1 geteuid
0.00 0.000037 18 2 1 arch_prctl
0.00 0.000035 35 1 set_robust_list
0.00 0.000025 25 1 set_tid_address
0.00 0.000000 0 1 execve
------ ----------- ----------- --------- --------- ----------------
100.00 1.004799 19931 17 total time 多少的时间在干什么
calls 调用多少次
usecs/call 每次系统调用所花的微妙
second = usecs x call

追踪这命令做了什么

[root@foundation0 ~]# strace -e openat  cp -r /etc/ /tmp

追踪这个命令做了什么打开的操作

案例

strace -e open ssh 192.168.6.22

有时ssh 连接会很慢

尝试strace跟踪,然后-e open



查看这个ssh读到的这个文件

nsswithch.conf:服务搜索顺序
文件/etc/nsswitch.conf(name service switch configuration,名字服务切换配置)规定通过哪些途径以及按照什么顺序通过这些途径来查找特定类型的信息。还可以指定某个方法奏效或失效时系统将采取什么动作。

可以发现他先从host表里面找,然后再从dns里面找

ssh 查dns,(因为ssh加密)加密通常和计算机名有关。通常给计算机名加密。ssh反查ip地址对应的计算机名是谁,查半天查不到 (etc/hosts lib_files.so.2)调整etc/hosts就可以也可以不做dns查询



目标主机不要做dns查询

[(本地的也可以改一改)]

简单的ls命令系统也做了很多工作,打开了很多文件

resident memory(物理内存) 和 virtual memory(虚拟内存)

内存过量分配

内存复用

华为内存复用150%

虚拟机的内存加起来超过宿主机

[root@servera /]# sysctl -a | grep overcom
vm.nr_overcommit_hugepages = 0
vm.overcommit_kbytes = 0 vm.overcommit_memory = 1 #默认0
vm.overcommit_ratio = 50 #默认50 vm.overcommit_memory
0 有多少就分配多少 (没有就没有)
1 总是过量分配 (瞬间很高,是可以接受的,这一瞬间,应用程序会很慢。总是过量那就会有问题)
2 平衡值 可以分配的虚拟内存为SWAP + RAM * 50%
设为2
vm.overcommit_ratio = 50 这个值才有意义
这个是比率可以调整
调高了对性能还是会有影响
测试
bigmem -b

swap对于应用程序来说也是物理内存

缓存

内存页状态

used 被使用不能分配

free 立即可分配

buff/cache clean page 可以释放,干净的页 它没有被改变,或者已经同步到磁盘

Dirty 已经改变,没有写到磁盘

回收脏页

后端有pdflush 监控内存页并回收

[root@servera ~]# sysctl -a | grep dirty
vm.dirty_background_bytes = 0
vm.dirty_background_ratio = 10
vm.dirty_bytes = 0
vm.dirty_expire_centisecs = 3000
vm.dirty_ratio = 40
vm.dirty_writeback_centisecs = 500
vm.dirtytime_expire_seconds = 43200

vm.dirty_expire_centisecs 脏页老化时间

脏页的过期时间,3000 = 1/100 秒 =30秒

没回收数据就丢了,不进硬盘

写到脏页是为了写缓存

写缓存,聚合io: 提升写性能

脏页不宜过长,容易丢失数据

如果写入的数据是随机的小IO,则建议将脏页老化时间设置得更长一些,让数据得以更多的聚合,反之,如果数据是连续的IO或者大IO,256K直接下发,不经过缓存

watch -n 1 'cat /proc/meminfo | grep Dirty'

拷贝数据,然后可以测出,确实是30m

vm.dirty_ratio 脏页站整个内存的比率

脏页占整个内存的比率 64G 32G = 50%

低水位: 当脏页的数量达到整个内存40%时,即便没有到老化时间,也会立即回收脏页

10%

来不及聚合就被回收

80%

脏页一直没回收,直到耗尽内存 波动大

384G*40% 那脏页也特别大啊

vm.dirty_bytes = 0

0为不关注

可以设置脏页达到10G时,会立即回收

vm.dirty_writeback_centisecs = 500

5秒监控一次,是否达到这个值

vm.dirty_background_ratio = 10

某一个进程脏页达到整个内存10%时会立即回收,一个进程消耗了太多了

vm.dirty_background_bytes = 0

进程消耗脏页达到这个值就被回收

sync立即回收所有脏页

查看回收内存

[root@servera ~]# watch -n 1 'cat /proc/meminfo  | grep Dirty'

Dirty:                 0 kB

写随机数到磁盘 以此测试
[root@servera ~]# dd if=/dev/urandom of=/dev/vdc Dirty: 14400 kB
达到14000左右就会被回收 [root@servera ~]# free -m
total used free shared buff/cache available
Mem: 1829 182 1459 16 187 1487
Swap: 0 0 0 因为到达了进程内存限制 10% (free+buff/cache) 提高比率
[root@servera ~]# sysctl -a | grep dirty
vm.dirty_background_bytes = 0
vm.dirty_background_ratio = 10
vm.dirty_bytes = 0
vm.dirty_expire_centisecs = 3000
vm.dirty_ratio = 40
vm.dirty_writeback_centisecs = 500
vm.dirtytime_expire_seconds = 43200
[root@servera ~]# [root@servera ~]# tail -n 2 /etc/sysctl.conf
vm.dirty_background_ratio = 20 [root@servera ~]# sysctl -p
vm.dirty_background_ratio = 20 那么脏页会达到30000左右 打开swap
[root@servera ~]# free -m
total used free shared buff/cache available
Mem: 1829 188 1412 16 227 1479
Swap: 5119 0 5119 发现,就算开了swap他依然直到30000
那么跟swap是没有关系的 关闭进程限制,以查看整体脏页限制
vm.dirty_expire_centisecs = 3000
vm.dirty_ratio = 40
谁先到谁回收
超过30秒回收
到达总体40%回收 注意
[root@servera ~]# sysctl vm.dirty_background_ratio=0
vm.dirty_background_ratio = 0
设置为0就不太好,没到多少就回收
根本不聚合
默认10% 你希望某一个应用程序得到io聚合,比如数据库,你希望它得到更多的聚合,你就设置
dirty_background_ratio多一点 系统整体不需要太低或太高就行

不回收数据有可能会丢,回收太快就没有聚合

pdflush

[root@servera ~]# sysctl  vm.drop_caches=3
vm.drop_caches = 3
[root@servera ~]# cat /proc/sys/vm/drop_caches
3
[root@servera ~]#

我们其实不需要手动清空缓存

系统会自己清空缓存,一旦内存紧张

更倾向清空它,还是使用swap

当读取随机IO较多时,建议保留cache

否则,建议清空cache

[root@servera ~]# sysctl -a | grep swapp
vm.swappiness = 15
这个默认60
取值范围0-100
当内存紧张时
设置为0则尽量不使用swap,去释放内存得到更多资源,如果这个数字越大,越倾向于使用swap资源,而保留cache tail -n 2 /etc/sysctl.conf
vm.swappiness = 5 当为5时
total used free shared buff/cache available
Mem: 1829 196 1173 16 458 1470
Swap: 5119 0 5119 [root@servera tuned]# bigmem 1100M
申请内存 total used free shared buff/cache available
Mem: 1829 1305 75 16 447 361
Swap: 5119 0 5119
他并没有使用swap,而是选择放弃缓存 内存不紧张你没必要释放cache,因为可以提高读性能。就算内存满了,他也会自动释放 你只有1800
你非要,要2000的内存
swap可也临时给你顶上,不然你的程序直接死机 total used free shared buff/cache available
Mem: 1829 1710 73 0 45 23
Swap: 5119 504 4615 我结束了bigmem,为什么swap还剩93
Swap: 5119 95 5024
当内存紧张时,内存中不用的数据暂时丢到swap中去。进程结束了,那个swap里的缓存数据不大且用不到。就还没被换到内存里来,还待在swap里

页中断,把数据都放到内存中,可以防止页中断。

minflt

主页中断 来自swap的内存,会影响性能

majflt

次页中断 不怎么影响性能

你分内存80%的内存来自swap性能变差

页切换

RHCA rh442 007 hugetlbfs strace命令追踪 脏页设置 内存分配的更多相关文章

  1. redis存在大量脏页问题的追查记录

    from:https://www.zybuluo.com/SailorXiao/note/136014 case现场 线上发现一台机器内存负载很重,top后发现一个redis进程占了大量的内存,TOP ...

  2. 【MySQL 读书笔记】SQL 刷脏页可能造成数据库抖动

    开始今天读书笔记之前我觉得需要回顾一下当我们在更新一条数据的时候做了什么. 因为 WAL 技术的存在,所以当我们执行一条更新语句的时候是先写日志,后写磁盘的.当我们在内存中写入了 redolog 之后 ...

  3. Mysql的刷脏页问题

    平时的工作中,不知道你有没有遇到过这样的场景,一条 SQL 语句,正常执行的时候特别快,但是有时也不知道怎么回事,它就会变得特别慢,并且这样的场景很难复现,它不只随机,而且持续时间还很短. 当内存数据 ...

  4. InnoDB引擎之flush脏页

    利用 WAL 技术,数据库将随机写转换成了顺序写,大大提升了数据库的性能,由此也带来了内存脏页的问题. 脏页会被后台线程自动 flush,也会由于数据页淘汰而触发 flush,而刷脏页的过程由于会占用 ...

  5. strace命令(收集整理,常看常新)

    starce的用途和参数:http://man.linuxde.net/strace(linux命令大全) strace命令是一个集诊断.调试.统计与一体 的工具,我们可以使用strace对应用的系统 ...

  6. 使用 Linux 的 strace 命令跟踪/调试程序的常用选项

    原文:http://linoxide.com/linux-command/linux-strace-command-examples/作者: Raghu 在调试的时候,strace能帮助你追踪到一个程 ...

  7. inux跟踪线程的方法:LWP和strace命令

    摘要:在使用多线程程序时,有时会遇到程序功能异常的情况,而这种异常情况并不是每次都发生,很难模拟出来.这时就需要运用在程序运行时跟踪线程的手段,而linux系统的LWP和strace命令正是这种技术手 ...

  8. linux跟踪线程的方法:LWP和strace命令

    摘要:在使用多线程程序时,有时会遇到程序功能异常的情况,而这种异常情况并不是每次都发生,很难模拟出来.这时就需要运用在程序运行时跟踪线程的手段,而linux系统的LWP和strace命令正是这种技术手 ...

  9. strace命令 二

    让我们看一台高负载服务器的 top 结果: top 技巧:运行 top 时,按「1」打开 CPU 列表,按「shift+p」以 CPU 排序. 在本例中大家很容易发现 CPU 主要是被若干个 PHP ...

  10. linux strace 命令

    有时小问题可以通过观察用户空间的应用程序的行为来追踪. 监视程序也有助于建立对驱 动正确工作的信心. 例如, 我们能够对 scull 感到有信心, 在看了它的读实现如何响应 不同数量数据的读请求之后. ...

随机推荐

  1. docker lnmp配置

    1.lnmp网络与目录规划 172.16.10.0/24 nginx:172.16.10.10 mysql:172.16.10.20 php:172.16.10.30 网站访问主目录:/wwwroot ...

  2. mysql binlog查看指定数据库

    1.mysql binlog查看指定数据库的方法 MySQL 的 binlog(二进制日志)主要记录了数据库上执行的所有更改数据的 SQL 语句,包括数据的插入.更新和删除等操作.但直接查看 binl ...

  3. Python多线程、多进程编程

    1 简介 参考:https://www.bilibili.com/video/BV1bK411A7tV?spm_id_from=333.999.0.0 python线程池ThreadPoolExecu ...

  4. Qt-ui的简单使用,常用控件(2)

    1  简介 本文主要介绍Qt ui界面的简单使用,介绍一些常用的控件. 参考视频:https://www.bilibili.com/video/BV1XW411x7NU?p=22 2  常用控件 常用 ...

  5. 2024-06-05:用go语言,给定三个正整数 n、x 和 y, 描述一个城市中由 n 个房屋和 n 条街道连接的情况。 城市中存在一条额外的街道连接房屋 x 和房屋 y。 需要计算对于每个街道数(

    2024-06-05:用go语言,给定三个正整数 n.x 和 y, 描述一个城市中由 n 个房屋和 n 条街道连接的情况. 城市中存在一条额外的街道连接房屋 x 和房屋 y. 需要计算对于每个街道数( ...

  6. 小程序视图组件 scroll-view

    视图容器组件 3.2.1.swiper 滑块视图容器. https://developers.weixin.qq.com/miniprogram/dev/component/swiper.html 3 ...

  7. SELinux 基本原理

    首发公号:Rand_cs SELinux 基本原理 本文讲述 SELinux 保护安全的基本原理 安全检查顺序 不废话,直接先来看张图 当我们执行系统调用的时候,会首先对某些错误情况进行检查,如果失败 ...

  8. 谁说.net core不好动态访问webservice?看这篇文章,C#快速实现动态访问webservice,兼容.net framework和.net core+

    前言:访问webservice,大多数人都是用服务引用的方式,但是这种方式比较麻烦,例如遇到服务更新了,你还需要手动更新你的服务引用,再重新发布,很麻烦.或者已有的一些例子,至少我看到的很多案例,动态 ...

  9. vuex中的数据在页面刷新后数据消失

    用sessionstorage 或者 localstorage 存储数据 存储: sessionStorage.setItem( '名', JSON.stringify(值) ) 使用: sessio ...

  10. Typora行内公式识别不了

    Typora行内公式识别不了,主要是因为行内公式属于LaTeX扩展语法,并非Markdown的通用标准 需要在Typora的"文件"-"偏好设置"-" ...