带着问题上路-Linux内存管理及进程管理

    xiaoxiao2024-12-28  64

    Linux进程调度以及配套的进程管理回答如下问题: 1. Linux进程和线程如何创建、退出?进程退出的时候,自己没有释放的资源(如内存没有free)会怎样? 回答:这是不可能的,Linux内核如果这么傻,它是无法应付乱七八糟的各种开源有漏洞软件的,所以进程死的时候,肯定是资源皆被内核释放的

    2. 什么是写时拷贝? 回答: 写时复制技术:内核只为新生成的子进程创建虚拟空间结构,它们来复制于父进程的虚拟究竟结构,但是不为这些段分配物理内存,它们共享父进程的物理空间,当父子进程中有更改相应段的行为发生时,再为子进程相应的段分配物理空间。

    3. Linux的线程如何实现,与进程的本质区别是什么? 在多进程情况下,每个进程都有自己的独立空间,而多线程情况下,同一进程内的线程共享进程的空间地址。因此,创建一个新的进程时就要耗费时间来为其分配系统资源,而创建一个新的线程花费的时间要少的多在系统调度方面,由于进程地址空间独立而线程共享地址空间,线程间的切换速度要远远快于进程间的切换在通信机制方面,进程间数据相互独立,彼此间通信要以专门的通信方式进行,通信时必须经过操作系统,而线程是数据共享的。

    4. Linux能否满足硬实时的需求? Linux内核可以做到硬实时吗? 不能? 为什么? 因为Linux从调度一个实时进程到该实时进程实际投入运行之间的时间不可控,因此无法给予有硬实时需求的可预期延迟。调度了一个实时进程,仅仅意味着它可以运行,并不意味着它实际运行了。两方面权衡,一方面调度一个进程说的是在该进程自己的立场上它可以运行了,另一方面,它能不能投入运行还要取决于当年正在运行的进程是否允许它立即运行,也即站在其它进程的立场上,是否同意RT进程运行

    5. 进程如何睡眠等资源,此后又如何被唤醒? 在Linux中,仅等待CPU时间的进程称为就绪进程,它们被放置在一个运行队列中,一个就绪进程的状态标志位为TASK_RUNNING。一旦一个运行中的进程时间片用完,Linux内核的调度器会剥夺这个进程对CPU的控制权,并且从运行队列中选择一个合适的进程投入运行。当然,一个进程也可以主动释放CPU的控制权。函数schedule()是一个调度函数,它可以被一个进程主动调用,从而调度其它进程占用CPU。一旦这个主动放弃CPU的进程被重新调度占用CPU,那么它将从上次停止执行的位置开始执行,也就是说它将从调用schedule()的下一行代码处开始执行。有时候,进程需要等待直到某个特定的事件发生,例如设备初始化完成、I/O 操作完成或定时器到时等。在这种情况下,进程则必须从运行队列移出,加入到一个等待队列中,这个时候进程就进入了睡眠状态。 Linux中的进程睡眠状态有两种: 一种是可中断的睡眠状态,其状态标志位TASK_INTERRUPTIBLE 另一种是不可中断的睡眠状态,其状态标志位为TASK_UNINTERRUPTIBLE 可中断的睡眠状态的进程会睡眠直到某个条件变为真,比如说产生一个硬件中断、释放进程正在等待的系统资源或是传递一个信号都可以是唤醒进程的条件。不可中断睡眠状态与可中断睡眠状态类似,但是它有一个例外,那就是把信号传递到这种睡眠状态的进程不能改变它的状态,也就是说它不响应信号的唤醒。不可中断睡眠状态一般较少用到,但在一些特定情况下这种状态还是很有用的,比如说:进程必须等待,不能被中断,直到某个特定的事件发生。

    7. 进程的调度延时是多少? 8. 调度器追求的吞吐率和响应延迟之间是什么关系? 吞吐和响应之间的矛盾 响应:最小化某个任务的响应时间,哪怕以牺牲其他任务为代价 吞吐:全局视野,整个系统的workload被最大化处理 首先我们在考虑调度器的时候,我们要理解操作系统的调度器设计目标追求两点:吞吐率大和延迟低。这两点是相互矛盾的。因为吞吐率大,势必要把更多的时间放到真实有用功上,而不是把时间浪费在进程上下文切换上。而延迟低,势必要求优先级高的进程可以随时抢占进来,打断别人,强行插队。 但是上下文切换的时间,对吞吐率来讲,本身是一个消耗。花了很多时间在上下文切换上,相当于做了很多无用功。这种消耗可以低到2us或者更低(这看起来没什么?),但是上下文切换更大的消耗不是切换本身,而是切换导致的cache miss

    9.CPU消耗型和I/O消耗型进程的诉求? https://blog.csdn.net/qq_37375427/article/details/83046906 进程分为:IO消耗型进程与CPU消耗型进程 IO消耗型(狂睡,等IO资源等):CPU利用率低,进程的运行效率主要受限于I/O速度 CPU消耗型(狂算):多数时间花在CPU上面(做运算) 一般而言,IO消耗型任务对延迟比较敏感,应该被优先调度。 它虽然时间都花在IO上,不关心CPU的性能,但是它关心的是是否能够及时的拿到CPU的使用权。也就是是否可以及时的被CPU调度。当自己完成了IO操作,但是一直不被CPU调度,那肯定也是不行的。比如,你正在疯狂编译安卓系统,而等鼠标行为的用户界面老不工作(正在狂睡),但是鼠标一点,我们应该优先打断正在编译的进程,而去响应鼠标这个I/O,这样电脑的用户体验才符合人性。

    10.Linux程优先级?实时的调度策略和普通调度策略有什么区别?** 回答:linux下的进程调度优先级是从-20到19,一共40个级别,数字越大,表示进程的优先级越低。默认时候,进程的优先级是0 实时调度是为了完成实时处理任务而分配计算机处理器的调度方法。实时处理任务要求计算机在用户允许的时限范围内给出计算机响应信号。实时处理任务可分为硬实时任务(hardrea[—timetask)和软实时任务(softreal—timetask)。硬实时任务要求计算机系统必须在用户给定的时限内处理完毕,软实时任务允许计算机系统在用户给定的时限左右处理完毕。   针对硬实时任务和软实时任务,计算机系统可以有不同的实时调度算法。这些算法采用基于优先级的抢先式调度策略,具体地说,大致有如下几类:   (1)静态表驱动模式。该模式用于周期性实时调度,它在任务到达之前对各任务抢占处理机的时间进行分析,并根据分析结果进行调度。   (2)静态优先级驱动的抢先式调度模式。该模式也进行静态分析。分析结果不是用于调度,只是用于给各任务指定优先级。系统根据各任务的优先级进行抢先式调度。   (3)基于计划的动态模式。该模式在新任务到达后,将以前调度过的任务与新到达的任务一起统一计划,分配CPU时间。   (4)动态尽力而为模式。该模式不进行任何关于资源利用率的分析,只检查各任务的时限是否能得到满足。   代表性的实时调度算法有两种。即时限式调度法(deadlinescheduling)和频率单调调度法(ratemonotonicscheduling)。   实时调度与非实时调度的主要区别是:   (1)实时调度所调度的任务有完成时限,而非实时调度没有。从而,实时调度算法的正确与否不仅与算法的逻辑有关,也与调度算法调度的时限有关。   (2)实时调度要求较快的进程或线程切换时间,而非实时调度的进程或线程的切换时间较长。   (3)非实时调度强调资源利用率(批处理系统)或用户共享处理机(分时系统),实时调度则主要强调在规定时限范围内完成对相应设备的控制。   (4)实时调度为抢先式调度,而非实时调度则很少采用抢先式调度

    11. nice值的作用是什么?nice值低有什么优势? Linux nice用来设置进程优先级,优先级的数值为-20~19,其中数值越小优先级越高,数值越大优先级越低,-20的优先级最高,19的优先级最低,默认的优先级数值为10。需要注意的是普通用户只能在0~19之间调整应用程序的优先权值,只有超级用户有权调整更高的优先权值(从-20~19)。

    12. Linux可以被改造成硬实时吗?有什么方案? https://blog.csdn.net/dog250/article/details/78373490 Linux内核可以做到硬实时吗? 不能? 为什么? 因为Linux从调度一个实时进程到该实时进程实际投入运行之间的时间不可控,因此无法给予有硬实时需求的可预期延迟。 那么如何对Linux内核增加硬实时保证呢? 首先,将中断线程话,保证它不再占用任意上下文,这保证了即便是中断被RT进程抢占了,也不会连累无辜的被它占用了内核栈的进程,其次,将普通进程中使用的spin lock改成可以睡眠的mutex,这样就可以保证在唤醒RT进程后立即使其投入运行。Linux的实时补丁就是干这个的

    多核、多线程的情况下,Linux如何实现进程的负载均衡?这么多线程,究竟哪个线程在哪个CPU核上跑?有没有办法把某个线程固定到某个CPU跑?多核下如何实现中断、软中断的负载均衡?如何利用cgroup对进行进程分组,并调控各个group的CPU资源?

    17. CPU利用率和CPU负载之间的关系?CPU负载高一定用户体验差吗? Linux内存管理回答如下问题: 答案: CPU利用率是对一个时间段内CPU使用状况的统计,通过这个指标可以看出在某一个时间段内CPU被占用的情况, 如果被占用时间很高,那么就需要考虑CPU是否已经处于超负荷运作, 长期超负荷运作对于机器本身来说是一种损害,因此必须将CPU的利用率控制在一定的比例下, 以保证机器的正常运作。Load Average是CPU的Load,它所包含的信息不是CPU的使用率状况,而是在一段时间内CPU正在处理以及等待CPU处理的进程数之和的统计信息, 也就是CPU使用队列的长度的统计信息。

    Linux系统的内存用掉了多少,还剩余多少?下面这个free命令每一个数字是什么意思?为什么要有DMA、NORMAL、HIGHMEM zone?每个zone的大小是由谁决定的?. 回答:

    因此x86架构中将内核地址空间划分三部分:ZONE_DMA、ZONE_NORMAL和 ZONE_HIGHMEM。 ZONE_HIGHMEM即为高端内存,这就是内存高端内存概念的由来。 在x86结构中,三种类型的区域(从3G开始计算)如下: ZONE_DMA 内存开始的16MB ZONE_NORMAL 16MB~896MB ZONE_HIGHMEM 896MB ~ 结束(1G)

    内存分区和内存映射区 首先明确内存分区和内存映射区的区别,内存分区指的是实际的物理内存的分区,内存映射区指的是每一个进程所拥有的虚拟地址空间的分区情况。 对于一个运行了linux的设备,通常存在如下分区:DMAzone、Normal zone、HighMem zone。 DMAzone存在的原因是有些设备存在硬件缺陷,无法通过DMA访问全部的内存空间,为了让这些设备在需要内存的时候能够每次都申请到访问能力范围内的内存空间,内核规定了一个DMA zone,当这些设备申请内存的时候,指定分配flag为GFP_DMA,它就可以拿到DMA zone的内存。也就是说如果我们的设备不存在这样的存在缺陷的设备,我们就不需要DMA zone,或者说整个Normal zone都是DMA zone。一般我们称DMA zong + Normal zone为Low memory zone。 HighMemzone存在原因是,当内存较大时,内核空间的3-4G空间无法把所有物理内存地址一一映射到内核空间,只能映射一部分,那么无法映射的那部分就是高端内存。 可以一一映射到内核空间的那部分内存,除去DMA zone就是Normal zone。 内存映射区可以简单的理解为,每个进程都拥有的4G空间。其中3-4G为内核空间,这部分空间又被划分为多个区域,其中与DMA zone和Normal zone存在一一映射关系的区域是DMA+常规内存映射区或者low memory映射区,同时也专门有个区域可以映射HighMem zone,但是并不存在一一映射的关系,这个区域是高端内存映射区。 所谓的一一映射,是指虚拟地址和物理地址只是存在一个物理上的偏移。

    系统的内存是如何被内核和应用瓜分掉的?

    底层的内存管理算法buddy是怎么工作的?它和内核里面的slab分配器是什么关系?

    频繁的内存申请和释放是否会导致内存的碎片化?它的后果是什么?

    Linux内存耗尽后,系统会发生怎样的情况? 回答:程序在1GB的电脑上面运行,申请2GB内存可以申请成功,但是在写到一定程度后,系统出现out-of-memory,上述程序对应的进程作为oom_score最大(最该死的)的进程被系统杀死。

    应用程序的内存是什么时候拿到的?malloc()成功后,是否真的拿到了内存?应用程序的malloc()与free()与内核的关系究竟是什么? 回答: 在应用程序里面malloc()成功的一刻,也不要以为真的拿到了内存,这个时候你的vss(虚拟地址空间,Virtual Set Size)会增大,但是你的rss(驻留在内存条上的内存,Resident SetSize)内存会随着写到每一页而缓慢增大。所以,分配成功的一刻,顶多只是被忽悠了,和你实际占有还是不占有,暂时没有半毛钱关系。

    25. 什么是lazy分配机制?应用的内存为什么会延后以最懒惰的方式拿到? 回答:你在应用程序里面malloc()成功的一刻,也不要以为真的拿到了内存,这个时候你的vss(虚拟地址空间,Virtual Set Size)会增大, 但是你的rss(驻留在内存条上的内存,Resident SetSize)内存会随着写到每一页而缓慢增大。所以,分配成功的一刻,顶多只是被忽悠了,和你实际占有还是不占有,暂时没有半毛钱关系此后我们调用brk()把堆变大到16KB,但是实际上它占据的内存rss还是8KB,因为第3页还没有写,根本没有真正从内存条上拿到内存。直到写第3页,堆的rss才变为12KB。这就是Linux针对app的lazy分配机制,它的出发点,当然也是防止应用程序傻逼了

    26. 我写的应用究竟耗费了多少内存?进程的vss/rss/pss/uss分别是什么概念?虚拟的,真实的,共享的,独占的,究竟哪个是哪个? 回答: Linux进程究竟耗费了多少内存,是一个非常复杂的概念,除了上面的vss, rss外,还有pss和uss,这些都是Linux不同于RTOS的显著特点之一。Linux各个进程既要做到隔离,但是隔离中又要实现共享,比如1000个进程都用libc,libc的代码段显然在内存只应该有一份。 仅从此图而言,进程1044的vss和rss分别是: vss= 1+2+3 rss= 4+5+6 但是是不是“4+5+6”就是1044这个进程耗费的内存呢?这显然也是不准确的,因为4明显被3个进程指向,5明显被2个进程指向,坏事是大家一起干的,不能1044一个人背黑锅。这个时候,就衍生出了一个pss(按比例计算的驻留内存, Proportional Set Size )的概念,仅从这一幅图而言,进程1044的pss为:rss= 4/3 +5/2 +6最后,还有进程1044独占且驻留的内存uss(Unique Set Size ),仅从此图而言,Uss = 6。

    27. 内存为什么要做文件系统的缓存?如何做?缓存何时放弃? Free命令里面显示的buffers和cached分别是什么?二者有何区别? 回答:“buffers” 表示块设备(block device)所占用的缓存页,包括:直接读写块设备、以及文件系统元数据(metadata)比如SuperBlock所使用的缓存页; “cached” 表示普通文件数据所占用的缓存页。 A buffer is something that has yet to be “written” to disk. A cache is something that has been “read” from the disk and stored for later use.

    交换分区、虚拟内存究竟是什么鬼?它们针对的是什么性质的内存?什么是匿名页?进程耗费的内存、文件系统的缓存何时回收?回收的算法是不是类似LRU?怎样追踪和判决发生了内存泄漏?内存泄漏后如何查找泄漏源?内存大小这样影响系统的性能?CPU、内存、I/O三角如何互动?它们如何综合决定系统的一些关键性能?
    最新回复(0)