GVKun编程网logo

linux-kernel – 如何在内存分配请求期间告诉内核释放缓存内存而不是OOM杀手终止应用程序

10

在这篇文章中,我们将为您详细介绍linux-kernel–如何在内存分配请求期间告诉内核释放缓存内存而不是OOM杀手终止应用程序的内容。此外,我们还会涉及一些关于C/C++在内存分配和释放时,小心野指

在这篇文章中,我们将为您详细介绍linux-kernel – 如何在内存分配请求期间告诉内核释放缓存内存而不是OOM杀手终止应用程序的内容。此外,我们还会涉及一些关于C/C++在内存分配和释放时,小心野指针、Docker如何处理OOM杀手和内存限制?、java 进程是如何在Linux服务器上进行内存分配的、Linux 5.3 内核系列已终止支持,建议用户升级至 Linux Kernel 5.4的知识,以帮助您更全面地了解这个主题。

本文目录一览:

linux-kernel – 如何在内存分配请求期间告诉内核释放缓存内存而不是OOM杀手终止应用程序

linux-kernel – 如何在内存分配请求期间告诉内核释放缓存内存而不是OOM杀手终止应用程序

我正在使用以下内核版本运行Ubuntu 10.04

Linux ip-10-0-1-119 2.6.32-343-ec2 #45-Ubuntu SMP Tue Feb 14 18:18:17 UTC 2012 x86_64 GNU/Linux

内存状态显示缓存正在使用RAM的最大份额.

ubuntu@ip-10-0-1-12:~$free -m
             total       used       free     shared    buffers     cached
Mem:          7702       7657         44          0         24       6137
-/+ buffers/cache:       1494       6207
Swap:            0          0          0

据我所知,操作系统会自动管理它并保持缓存中RAM的最大份额,以最大限度地降低I / O的成本.

问题是在我们的应用程序需要内存时负载很重,如果物理RAM中没有相同的数量,OOM杀手终止应用程序.

我如何调整我的内核,以便如果我的应用程序有任何内存请求,内核应该释放一些缓存内存为我的应用程序腾出空间而不是OOM杀手终止它?

解决方法

通常,linux会为您的应用程序清除缓存.您可以做的是将您的申请从OOM杀手中排除. OOM杀手不会终止你的申请.
echo -17 > /proc/PID/oom_adj

PID应该是程序的PID.

C/C++在内存分配和释放时,小心野指针

C/C++在内存分配和释放时,小心野指针

普通的野指针

在C/C++中进行内存分配之后,如果在使用过之后释放了内存,一定要注意将指针置为NULL,否则指针将变成野指针。

示例代码如下

char *p = (char *)malloc(sizeof(char));
//exe task

free(p);//若不释放指针p所指内存空间,则会造成内存泄漏。

p = NULL;//若不置指针p为NULL,则可能会被误以为是合法的,就会成为野指针。
         //如果后续无意中引用了p就可能会造成错误

...... // do something else

因为在通过 free(p)释放了内存之后,只是将内存进行了释放,不能再使用这块内存,但是这时候p还是会指向这块内存(所以还有通过指针访问这块内存的可能性),所以为了安全,为了不出现后续无意中引用了p就可能会造成错误的情况,就需要在释放了内存之后,显式的将指针置为NULL

这些编程中的细节的规范是极其重要的,编程其实是一个庞大的而且其中有着极其多的复杂的细节的工作,一个好的开发者一定要能够在编码的细节、代码的规范上面做得好才行

另一种形式的野指针

还可能存在这样的情况:有多个指针指向同一块地址,通过一个指针释放该内存空间后,这个指针也确实被置为null了,但是还存在另外的指向该内存的指针来访问该空间的情况。

这也是另一种需要谨慎对待的野指针,所以也是需要考虑和防止的!

Docker如何处理OOM杀手和内存限制?

Docker如何处理OOM杀手和内存限制?

我有一个docker容器,它通过bash脚本启动一个简单的java(基于jgroups的)应用程序. java进程通过Xmx限制128m,容器允许使用256m(禁用交换).不幸的是,我不时会面对以下OOM消息:

Jul 07 02:43:54 ip-10-1-2-125 kernel: oom_kill_process: 16 callbacks suppressed
Jul 07 02:43:54 ip-10-1-2-125 kernel: java invoked oom-killer: gfp_mask=0x2400040,order=0,oom_score_adj=0
Jul 07 02:43:54 ip-10-1-2-125 kernel: java cpuset=0ead341e639c2f2bd27a38666aa0834c969e8c7e6d2fb21516a2c698adce8d5f mems_allowed=0
Jul 07 02:43:54 ip-10-1-2-125 kernel: cpu: 0 PID: 26686 Comm: java Not tainted 4.4.0-28-generic #47-Ubuntu
Jul 07 02:43:54 ip-10-1-2-125 kernel: Hardware name: Xen HVM domU,BIOS 4.2.amazon 05/12/2016
Jul 07 02:43:54 ip-10-1-2-125 kernel:  0000000000000286 000000006ffe9d71 ffff8800bb3c7c88 ffffffff813eb1a3
Jul 07 02:43:54 ip-10-1-2-125 kernel:  ffff8800bb3c7d68 ffff880033aea940 ffff8800bb3c7cf8 ffffffff812094fe
Jul 07 02:43:54 ip-10-1-2-125 kernel:  000000000000258c 000000000000000a ffffffff81e66760 0000000000000206
Jul 07 02:43:54 ip-10-1-2-125 kernel: Call Trace:
Jul 07 02:43:54 ip-10-1-2-125 kernel:  [RSS_huge:135168KB mapped_file:16
Jul 07 02:43:54 ip-10-1-2-125 kernel: [ pid ]   uid  tgid total_vm      RSS nr_ptes nr_pmds swapents oom_score_adj name
Jul 07 02:43:54 ip-10-1-2-125 kernel: [26659]     0 26659     1127       20       7       3        0             0 sh
Jul 07 02:43:54 ip-10-1-2-125 kernel: [26665]     0 26665     1127       20       7       3        0             0 run.sh
Jul 07 02:43:54 ip-10-1-2-125 kernel: [26675]     0 26675   688639    64577     204       7        0             0 java
Jul 07 02:43:54 ip-10-1-2-125 kernel: Memory cgroup out of memory: Kill process 26675 (java) score 988 or sacrifice child
Jul 07 02:43:54 ip-10-1-2-125 kernel: Killed process 26675 (java) total-vm:2754556kB,anon-RSS:258308kB,file-RSS:0kB
Jul 07 02:43:54 ip-10-1-2-125 docker[977]: Killed

如您所见,我的应用程序的RSS大约只有64M.但由于某些原因,cgroup的RSS为256M(包括128M的大页面).

这是一种操作系统缓存吗?如果是这样,为什么OOM在杀死用户的应用程序之前不会刷新它们?

最佳答案
哦!看起来我忘了发布答案.

上面的问题是我的java进程,它与docker无关.我错误地认为OOM报告以Kbytes打印RSS.这是错的 – OOM报告打印的页面数量通常为每个4K.

就我而言,pid 26675为RSS获取64577页,等于(64577 * 4K)258’308 KBytes.添加2个bash进程为我们提供了当前CGroup的限制 – 262144kB.

因此,进一步的分析必须在JVM字段中:堆/元空间分析,本机内存跟踪,线程等……

java 进程是如何在Linux服务器上进行内存分配的

java 进程是如何在Linux服务器上进行内存分配的

这篇文章主要介绍了java 进程是如何在Linux服务器上进行内存分配的,帮助大家更好的理解和使用Java,感兴趣的朋友可以了解下

众所周知,Java进程在启动的时候我们可以通过 -xms 和-Xmx来设置内存的上限和下限。直到我发现使用top命令监控的Java进程在-xms设置4g的情况下占用的内存并不是4g,这就产生了一个疑问Linux服务器的内存到底是如何进行分配的。

于是乎,我查阅了一些知乎,课程以及Linux相关的书籍。这里分享并记录的一下相关的知识。

在Linux上运行的进程不仅限于Java。都有一个概念,逻辑内存(Logic Memory),而物理机真是持有的内存,我们称为 物理内存(Physic Memory)。

进程在开始运行时并不会直接分配物理内存,进程只是傻乎乎的以为自己持有了内存,也就是逻辑内存。当程序运行需要内存分配的时候,Linux服务器会以页的(Page)至小4k的方式分配,并一对一映射物理内存和逻辑内存的关系,看到了吗这里其实用了代理的思想是得内存的分配进行了解耦。

这样做的好处是什么呢? 1进程之间相互隔离 2进程自己认为占有了一段独立连续的内存 3可以申请比物理内存更大的内存空间。

第三点怎么理解呢?其实Linux在这里设计了一种机制叫Swap 就是在进程分配的内存空间超过物理内存的时候,如果各个进程运行所占的内存真的有这么多,超过了物理内存就会触发Swap,把不持有cpu的部分进程的内存数据和磁盘进行io数据交换。因为cpu一时间不可能超过所有占有的内存,所以这种优化就造就了能多申请一些内存,大概是原来内存的2-3倍,这就很可观了,毕竟内存是非常贵的。

Swap虽然好,也带来了一些问题。

比如频繁的Swap,这会导致内存操作转化为磁盘的的IO操作,拖慢应用进程的运行速度。所以说Swap在我的理解里属于可以应急不使进程崩溃,适当使用可以减少成本,过分了不当人的使用就会被反噬的机制。

当然如果太不当人,进程还是会崩溃了,Swap是一个类似Buffer的机制,有大小的。超过设置的上限,Kernel内核就会触发OOM Killer,杀死一部分进程腾空间。

Linux 5.3 内核系列已终止支持,建议用户升级至 Linux Kernel 5.4

Linux 5.3 内核系列已终止支持,建议用户升级至 Linux Kernel 5.4

上周,Linux 内核开发人员 Greg Kroah-Hartman 宣布了 Linux 5.3 内核系列的第 18 个维护更新(5.3.18)。该版本共更改了 59 个文件,插入 369 项 / 移除 329 项。此外开发者指出,这将是 Linux 5.3 内核系列的最后一个维护更新。随着 Linux Kernel 5.3 抵达 EoL,官方建议用户及时更新至 Linux Kernel 5.4,以获得全面的支持与保障。

Greg Kroah-Hartman 在邮件公告中称,Linux Kernel 5.3 支持到期后,将不再收到关键安全问题或 bug 的维护更新,感兴趣的朋友可翻阅 5.3.y 的 Git Tree 。

无论是普通 Linux 用户、还是发行版供应商,再次都强烈建议大家将 OS 升级到最新的 Linux 5.4 内核系列。若当前暂时无法实现,也请至少更新至 5.3.18 版本。

你可以从 Kernel.org 官网下载上述两个版本,但需要手动编辑和实施安装。不过在从 Linux 5.3 内核升级之前,也可适当等待您喜欢的 GNU / Linux 稳定版软件包进入资源库。

至于 Linux Kernel 5.4 的新功能,主要是包括了期待已久的微软 exFAT 文件系统支持,以及人们期盼已久的“锁定”(Lockdown)安全功能。

我们今天的关于linux-kernel – 如何在内存分配请求期间告诉内核释放缓存内存而不是OOM杀手终止应用程序的分享就到这里,谢谢您的阅读,如果想了解更多关于C/C++在内存分配和释放时,小心野指针、Docker如何处理OOM杀手和内存限制?、java 进程是如何在Linux服务器上进行内存分配的、Linux 5.3 内核系列已终止支持,建议用户升级至 Linux Kernel 5.4的相关信息,可以在本站进行搜索。

本文标签: