在这篇文章中,我们将为您详细介绍linux-kernel–如何在内存分配请求期间告诉内核释放缓存内存而不是OOM杀手终止应用程序的内容。此外,我们还会涉及一些关于C/C++在内存分配和释放时,小心野指
在这篇文章中,我们将为您详细介绍linux-kernel – 如何在内存分配请求期间告诉内核释放缓存内存而不是OOM杀手终止应用程序的内容。此外,我们还会涉及一些关于C/C++在内存分配和释放时,小心野指针、Docker如何处理OOM杀手和内存限制?、java 进程是如何在Linux服务器上进行内存分配的、Linux 5.3 内核系列已终止支持,建议用户升级至 Linux Kernel 5.4的知识,以帮助您更全面地了解这个主题。
本文目录一览:- linux-kernel – 如何在内存分配请求期间告诉内核释放缓存内存而不是OOM杀手终止应用程序
- C/C++在内存分配和释放时,小心野指针
- Docker如何处理OOM杀手和内存限制?
- java 进程是如何在Linux服务器上进行内存分配的
- Linux 5.3 内核系列已终止支持,建议用户升级至 Linux Kernel 5.4
linux-kernel – 如何在内存分配请求期间告诉内核释放缓存内存而不是OOM杀手终止应用程序
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杀手终止它?
解决方法
echo -17 > /proc/PID/oom_adj
PID应该是程序的PID.
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容器,它通过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,感兴趣的朋友可以了解下
众所周知,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 内核开发人员 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的相关信息,可以在本站进行搜索。
本文标签: