嵌入式linux 线程栈大小 4k,Linux系统调优

Linux在进行系统调优的时候,首先要考虑整个操作系统的结构,然后针对各个部分进行优化,下面展示一个Linux系统的各个组成部分:

6b007bc81c915ba5fb85a7ba389f38db.png

有上图可以看出,我们可以调整的有应用程序,库文件,内核,驱动,还有硬件本身,所以接下来讲对这些进行详细的介绍,从而是系统的性能有所提高。

内核子系统中主要包括一下几个方面:

1. network(网络)

2. IO(输入输出子系统)

3. process(进程)

4. memory(内存)

5. File System(文件系统)

一、 Linux的进程管理

1、进程的定义:进程是计算机资源分配单位,主要包括对系统资源的调度,如CPU时间,内存空间,是一个程序执行的一个副本。他们还包括一系列的资源,如文件的打开,释放信号,内核内的数据,进程状态,内存地址的映射,执行的多个线程,和数据段的全局变量。

2、进程状态:running(运行)、interruptible(可中断的睡眠态)、unitertible(非可中断的睡眠态)、stopped(停止状态)、zombie(僵死态)

89364401bf23c26672f22b96c648ae6a.png

Task_Running:一个进程要么在CPU上执行,要么等待CPU的时间再执行;

Task_Interruptible:一个处于sleeping状态的进程,直到环境条件改变,重新挂起一个硬件中断,使用系统释放的资源,或者释放一个信号,这个信号可以唤醒这个进程到Task_Running状态,一般是一个IObound类型的;

Task_uninterruptible:这个和Task_Interruptible是一样的,但是CPU bound类型的。

Task_stopped:程序执行已经完成,这个进程在接受到SIGSTOP、SIGTSTP, SIGTTIN, or SIGTTOU signal这些信号的时候,这个进程进入这个状态;

Task_zombie:子进程执行完成,但是该子进程的父进程已近dead,无法回收这个子进程所占用的资源;

3、进程周期:一个子进程都是父进程的一个副本,所以除了PID和PPID不同,其他的都是相同的,而子进程在执行一个程序的时候,需要在单独在一个地址空间内进行,当执行完成之后,子进程锁占用的资源要有父进程进行回收,这就是一个进程的生命周期;

4、线程的概念:线程是比进程资源更小的资源调度单位,所以也叫轻量级的进程(LWP)

而线程的调度更加节省系统的资源,如果使用的是进程,即使是相同的进程也需要分配两份资源,而线程就不同了,它可以在同一个进程中实现资源的重复利用,这就是nginx的性能比使用apache性能要好的原因,因为nginx是基于线程的,而apache的prefork模式的是基于进程的,每一个进程连接都要分配4M的空间,而每一个线程确非配4k由此可以找出显著的差别了,关于进程和线程资源调分配对比,我给大家准备了一个图,可以简单的看出他们之间的区别:

3621f05948b4385861fc1cfb73773d70.png

5、进程的调度:进程调度就是按照一定的调度算法,来实现不同进程之间的切换,常见的调度算法有一下几种:

O(1)调度器<2.6之后>这种在调度的时候一秒一个,能实现公平的调度,公平分配时间,但是再有的时候会浪费时间,如edit和movie之间,edit就会浪费时间。

O(log n)

O(n)

O(n^2)

O(2^n)

为了解决O(1)的不足,又引用了deadline,deadline有三个队列,活动队列,死亡队列,deadline队列,为不同的进程做一个计数器,到时间就不管进程优先级的高低,而是“见死就救”。(deadline现在在磁盘上使用)现在进程调度使用的是CFS(完全公平调度算法)调度算法:不再为每一个进程分配一个时间片,而是按照进程来分配一个时间比例。

6、进程的种类:交互式进程、批处理进程、实时进程;

7、进程的优先级:

静态优先级:1-99,100-139

动态优先级:动态优先级调整的范围100-139,通过调整nice值进行调整,调整后表现为nice值。nice值范围在-20—19

实时优先级:0-99(数字越大,优先级越高)

8、进程调度策略:

SCHED_FIFO:先进先出【1-99】,只能调度实时优先级进程;

SCHED_RR:轮调 引入了时间片,是FIFO改进后的算法,只能调度实时优先级进程;

SCHED_OTHER:调度传统的分时进程【100-139】;

SCHED_BATCH:只用来调度nice=0或优先级为120的;

使用#ps axo comm.,rtprio显示实时优先级;

实时进程定义启动使用的调度类别和指定优先级:

chrt -f [1-99] /path/to/program arguments //添加到FIFO队列中去

chrt -r [1-99] /path/to/program arguments //添加到RR队列中

nice&&renice调整优先级

查看系统的瓶颈是否是CPU

1.平均负载 yum install sysstat

负载的三个平均值不能大于3

w

uptime

top

sar -q 1 3

vmstat 1 5

2.CPU的利用率

mpstat -p 60%在用户空间就是正常的

sar -P ALL 1

iostat -c 1

cat /proc/stat

9、cache 缓存:

缓存分为cache-hit和cache-miss

#yum install x86info

#x86info –c 查看cpu的缓存类型

#valgrind --tool=cachegrind ls 查看缓存命中情况

# dmesg | grep -i cache 查看缓存大小

10、多个CPU和多核CPU之间进行均衡

#watch -n .5 'ps axo comm,pid,psr | grep httpd ' 查看进程在哪个CPU上

taskset [opts]

#taskset -c -p CPULIST PID 把某一个进程绑定到一个特定的CPU上

#taskset -c -p 0 5533 把5533进程绑定到0号CPU上

这种能提高缓存命中率,但是对均衡有缺陷

11、调度域:就是将某些进程绑定在多个CPU组成的域中。调度域的作用就是把CPU组定义为调度域,一个CPU集合就是一个调度域,配置本地调度域:

#mkdir /cpusets

#vim /etc/fstab 添加一下内容

cpuset /cpusets cpuset default 0 0

#cd /cpusets

#ls

bf404badf42c23747e365f52ac8ad276.png

#mkdir ro

#cd ro

#echo 0 > cpus 这样就建立了一个ro的调度域,同时绑定到第一个CPU上了;

12、进程的地址空间

一个进程在使用自己的内存空间进行工作的,所以这就导致了每一进程都有自己的地址空间,每一个进程都有自己的特点和数据大小,进程必须持有大量的数据尺寸,对于Linux内核来说,每个进程使用动态内存分配的是结构化的,具体如下图所示:

6bf47fcf68e0091a7bc03fe0112c41ba.png

所以进程可以分为代码段、数据段、BBS、堆、栈。

二、 内存管理

1、内存管理要想了解内存的调度机制,下面我就结合下图进行简单的阐述:

e944b8331897aa6b940c2f7d6feae1af.png

我就从左向右一步一步的介绍用户发出个请求,通过调用库文件,有用户空间进入内核空间,在内核空间中把数据从磁盘中读入内存中进行操作,操作完成之后,在同步到磁盘中,而为了提高CPU的工作效率,使用MMU(memory manger unit,内存管理单元)来替代CPU来执行整个进程的调度,在这个过程中,首先要交换分区slab allocator目录找到对应的资源所在的位置,然后到对应的内存空间或磁盘空间中去寻找,当然为了避免内存回收的外碎片,引入了zoned buddy allocator,这个就是合理分配内存资源的,等到进程调度占用的空间使用完成之后,需要回收资源,这里就是用到了pdflush,就是讲内存中dirty pages的数据同步到磁盘上去。

PTE:page tables 页表项

PAE:物理地址扩展

TLB:transition lookaside buffers 转换后缓冲器

只用x86info –c 和 dmesg可以查看

2、内存空间结构:

下图是对32位的系统和64位的系统内存空间的一个对比

3e035948344ded4b24e7516965636778.png

由于硬件设备的限制,所以内核不能把所以的page视为相同的,所以出现了如上图的Zone,下面开始详细的介绍这些内容了:

1.在32位的系统上一个单独的进程最大的地址空间是4G(2^32),这4G被分为1G的内核空间和3G的用户空间;其中1G的内核空间是用来做页表的虚拟地址和物理地址进行映射关系的,另外3G是用户空间;

在1G的内核空间中,其中有16MB是用来做DMA(直接内存区域)的,这个区域包括pages;从16MB-896MB这期间的880MB是内核使用的,还有128MB是用来做映射的,从虚拟地址空间映射到物理地址空间上去;而上面的3G就是整整的地址空间了。而对于64位的操作系统的空间,有1G是用来做DMA的,区域的都是用来做实际的地址空间的,所以在服务器上,不带考虑的直接装64位的系统;

2. 通常出现缺页异常的原因:数据还在磁盘上、数据在交换分区上,如果数据持续从交换分区上进行数据调度的话,那么这就直接可以断定是内存瓶颈,内存不够用,剩下的就不解释了,你懂的,扩展内存,呵呵!

3.查看各个进程的资源使用情况的方法:

#cat /proc/PID/status 或cat /proc/PID/statm

482a37f7c06f93b68f56cdfd8d362f72.png

然后你就可以查看一下里面的内容了,系统每启动一个进程,都会占用一定的地址空间。

也可以使用图形化界面进行查看

#gnome-system-monitor

#pmap +PID 查看进程对应的库文件,也可以定位内存的瓶颈

#yum install glibc-utils

#memusage +COMMAND 查看单个进程占用的内存,同时以条形框的形式展示

#memusage –help可以获取该命令的更多的帮助信息

cb391cc4003dbd642a55b4f4f5c41925.png

#ps axo minflt,majflt 看所有进程的缺页异常发生情况

6dbfc80f16ca361c112d1ecd4c8ed3d4.png

其中minflt表示的是磁盘的使用情况,而majflt表示交换分区使用的情况,根据这些信息可以判断,如果长期使用交换分区的话,那么就是内存瓶颈了。

4.内存的配额分为一下几种:

(1)Process forks or execs child process

(2)New process requests memory

(3)New process uses memory

(4)Process frees memory

5.内存的类型:

SRAM:静态(static RAM)

DRAM:动态 (Dynamic RAM)

SDRAM

DDR

RDRAM(服务器上使用,窄带,有奇偶校验的内存)

6、提高TLB的性能

TLB:(transition lookais buffer)转换后援缓冲器,就是存放虚拟地址到物理地址转换的表,也称为页表缓冲;

TLB存放的页面在32位系统上支持4k和4M两种,在其他系统上就更多了,如果想了解,可以借助帮助文档

#yum install kernel-doc

安装完成之后位于 /usr/share/doc/kernel-doc-2.6.18/Documentation中;

如果我们想让TLB的值大点,也就是做成Hugetlb Page(大页表)可以设置内核参数,这样可以提高TLB缓存的命中率,降低PTE的方位次数,来加速地址转换的速度;

调整TLB值的大小:

/etc/sysctl.conf

vm.nr_hugepages=n

临时生效:

#echo 4 > /proc/sys/vm/nr_hugepages

#sysctl -w vm.nr_hugepages=n

永久有效:

#vim /etc/sysctl.conf

#sysctl -p 保存,生效

为了以后使用大页表,我们可以做一个大页表文件系统

#mkdir /hugepages

#mount -t hugetlbfs none /hugepages 在以后就如果使用到了,就可以直接使用了;

当然为了详细的观察进程详细的调度情况,也可以追踪系统调用

#strace -p PID 查看进程详细调度的进程

#strace ls 可以看到所发出指令的详细的系统调用

#strace ls -o /tmp/tmp.txt 保存在指定的文件中。

#strace -c -p PID 统计系统调用时间和所调用的次数,结合这些结果进行分析

7、内存使用应遵循的策略:

a.减小内存小对象的消耗,使用的工具有slab cache

b.降低那些比较慢的系统服务时间:

i.文件系统的:buffer cache(slab cache)

ii.DISK IO: page cache

iii.Internetprocess:shared memory

iv.network IO:buffer cache,arp cache,connection tracking (buffer是解决两端速率不匹配的,而cache是为了重复使用,提高缓存命中率的)

结合上面的理论,接下来就是做详细的内存内核参数的调整的过程了:

1、vm.min_free_kbytes 至少要在内存中保留多大的K字节的空间

说明:当一个应用反复使用和释放大的内存,磁盘的带宽下,CPU使用低下,内存小,需要改变上面的参数,如果改小了,这样就会导致服务时间降低,其他应用程序无法有足够的内存,对zone_nomal照成很大的压力;默认是2890

2、vm.overcommit_memory 内存过度使用,这个参数有三个数值可以设置0,1,2

0|拒绝过度使用(默认)

1|总是过度使用 (不建议)

2|仅能使用所有的RAM和swap的一个百分比建议设置为30,50%已经是大的了)尽可能根据committed_AS为参照来设置

3、vm.overcommit_ratio 过度使用的比,就是上面swap的比(建议设置为30%,50%已经是较大的了)默认:50

4、调整slab缓存小内存对象,缓存的是文件的innode(索引),每一种slab只能缓存一中小内存对象;

该文件在/proc/slabinfo文件中,我们可以看一下:

a6b3d0a87e296694123eacc5a51a2535.png

这个问价中可以该的值有limit,batchcount,sharedfactor,其中limited=N*batchcount

如:

#echo “ext3_inode_cache 108 27 8” >/proc/slabinfo

#slabtop //查看当前slab分配的信息

同样可以使用vmstat –m 也可以查看当前slab分配信息

fc02b631085705a231420bfe9043e669.png

5、调整ARP cache:

#cat /proc/net/arp

aad250f71a26858a9d6ea2d7cf163633.png

可以看出现在arp缓存

也可以使用一下命令进行查看

#arp –a

#ip neigh show

arp -d hostname 删除arp缓存

ip neighbor flush dev eth0 标记为失效,过一会就会清空

当让为了减少arp cache占用系统资源,可以设置其存储的条目

net.ipv4.neigh.default.gc_thresh1 定义缓存上线,当缓存大于多少的时候就做清理(默认128)

net.ipv4.neigh.default.gc_thresh2 软上线 512

net.ipv4.neigh.default.gc_thresh3 硬上线 1024

net.ipv4.neigh.default.gc_interval 缓存收集垃圾时间 默认30s

这些是对arp缓存大小的设置;

6、page cache :page缓存的是数据;

使用到的场所:直接读、读写、读写快设备、访问内存mapped files、访问swap mapped files

vm.lowmem_reserve_ratio 低地址空间中预留的空间的百分比,一般指的是zone_normal放置OOM(内存地址耗尽);

vm.vfs_cache_pressure 定义内核回收slab cache、pagecache、swapcache中的内存的倾向性,默认是100,如果小于100,倾向性变小,如果设置为0,就不会回收pagecache、swapcache中的内存(不建议),如果经常打开文件,要增大这个值,能快速回收内存,如果有足够大的内存,可以维持在100,一般不需要降低这个值;

vm.page_cluster 页簇:控制物理内存数据交换到交换分区的时候,一次交换的多少个页面数2^n 这个值默认是3,也就是8个页面,应用程序频繁使用交换分区的时候,可以调大点;

vm.zone_reclaim_mode 内存区域回收的模型,当一个区域的内存消耗完的时候,如何回收此区域的空间,其值有:1(打开回收机制)、2(将此内存的章页同步到磁盘在回收)、4(回收交换页面所占用的空间)

7、anonymous pages:匿名页面

匿名页面主要包括程序数据,arrarys,heap,allowcations等

b42dc9f1068754cc3f7b0b808754ed14.png

8、SysV IPC interprocess communication 进程间通信:

*1.semaphores 信号

调整:

kernel.sem

cat /proc/sys/kernel/sem

250 每个数组信号量

32000

32

128 可以所使用的数组

*2.Messageing queues 消息队列(rubbit MQ)通过交换信息

调整:

kernel.msgmnb

16384 一个单独的消息队列能容纳多少消息信号

kernel.msgmni

16 消息队列最大消息队列数

kernel.msgmax

8192 单个消息最大上线8k

*3.shared memory 共享内存

调整:

kernel.shmmni

4096 共享内存段的最大数目

kernel.shmall

2097152 一次共享页面的值

kernel.shmmax

shmall*4k 共享内存段的大小可以被创建

使用ipcs命令查看当前机器进程间通信的机制

ipcs -l显示进程间通信的限制

c4310cc83bc7f34eacd475ed44dccdea.png

如果文件的修改不是太多,可以把数据放在/dev/shm中,这个直接写入内存,但是一旦断电,数据就会丢失

9、内存详细使用情况的命令:

free -m 显示内存使用情况

page tables:cat /proc/vmstat

system memory:cat /proc/meminfo (total physical memory,cache,active use,inactive) 使用vmstat -s

#yum install sysstat

sar -r 1 10 (每个一秒取一次,取十次)

10、页面分类:

1.free

2.inactive clean 可以被直接回收使用

3.inactive dirty 页面中有数据没有同步到磁盘上去,只要同步到磁盘上去了,就能回收

4.active 正在被使用的页面

Bubby system:伙伴系统,是避免内存回收的外碎片的,保存内存空间是连续的一片空间

内核中的有个线程叫kswapd来回收空闲分区,把内存中使用较少的(非活动clean状态的)放到交换分区,腾出空间供其他的使用

使用vmstat -a |-s 显示页框使用状态

页面主要作用:page cache 和进程地址空间,所有回收page cache中的页面

11、如何回收dirty pages:

1.同步到磁盘上,靠的是pdflush的内核线程(每隔一段时间就会同步,可以多个同时运行的,可以定义pdflush的数目,如CPU,DISK多,可以在一个CPU上一个,提高并发能力)

2.放到交换分区

vm.nr_pdflush_threads 就是定义pdflush线程个数,建议一个磁盘一个pdflush线程

vm.dirty_background_ratio 当脏页总数占整个内存比例的时候,启动pdflush

vm.dirty_ratio 某一个单进程的脏页所占用的比例,然后启动pdflush进行刷写

vm.dirty_expir_centisecs 每隔一段时间进行一次刷写操作(默认30s,0表示禁用)

vm.dirty_writeback_centisecs 默认5s,定义一个数据修改超过这个时间就可以刷写了

12、如何回收干净页面:

sync

fsync

echo s > /proc/sysrq-trigger 手动同步到磁盘

echo x > /proc/sys/vm/drop_caches

x=

1 free pagecache

2 free dentries and inodes

3 buffer and cache

out-of-memory killer进程在内存占用满了,就开始杀死一些进程

/proc/PID/oom_score 进程的分数,分数越大,就会在内存oom的时候最先杀死

13、优化OOM策略:

echo n >/proc/PID/oom_adj

echo f > /proc/sysrq-trigger 手动杀死进程

vm.panic_on_oom=1 禁止oom-kill ,但是内存耗尽也会照成系统恐慌

14、探测内存泄漏:一个进程退出的时候,内存未释放

内存泄漏分为两种:

1.虚拟(virtual)内存泄漏:只申请,但不使用

2.real:内存释放失败

#sar -R 查看内存申请、释放情况,正数是申请的,负数是释放,其中frmpgz正好相反

#yum install valgrind

#valgrand --tool=memcheck ls 查看内存泄漏

**作为管理员要经常关注内存是否泄漏

15、swap 交换分区:

swap-out=page-out 就是把内存中的数据放到交换分区

swap-in :把内存中的数据放到交换分区;

那些pages要进行交换:

inactive pages

anonymous pages

16、提高swap的性能:

1.降低决策时间 :快速换入唤出小页面,匿名pages

2.降低访问次数:做swap集群,多个分区做相同的优先级

3.降低服务时间:尽可能使用分区,不实用文件;尽量把交换分区放到磁盘外道;把交换分区放到raid0上

vm.swappiness 定义多大倾向唤出交换分区的匿名页,里面是一个%比,达到了就使用交换内存,如果不想使用交换分区,可以把值设置小于100,默认是60

17、交换分区的大小:

批处理服务:> 4*RAM

数据库服务:<=1G

应用程序服务:>=0.5*RAM

vm.page_cluster=n (2^n个页面)

vm.swap_token_timeout 一旦发现交换分区频繁的不参与这个的时间

18、监控内存工具:

vmstat -n 显示内存和swap分区的数据

sar -r 显示内存和swap分区的数据

sar -R 显示内存的数据

sar -W 像是swqp数据

sar -B 显示页面的数据

还有网络、IO调优待续。。。

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值