当Linux用尽内存

升级内核遇到的问题汇总 卡在starting kernel 注意一下设备树和自己的内核是不是匹配的 Waiting for root device /dev/mmcblk0p2… [ 1.041445] platform regulatory.0: Direct firmware load for regulatory.db failed with error -2 [ 1.050235] cfg80211:... 阅读详情

 

也许你很少面临这一情况,但是一旦如此,你一定知道出什么错了:可用内存不足或者说内存用尽(OOM)。结果非常典型:你不能再分配内存,内核会杀掉一个任务(一般是正在运行那个)。一般半随着大量的交换读写,你可以从屏幕和磁盘动向看出来。

这个问题下面隐含着别的问题:你需要分配多少内存?操作系统给你分配了多少?OOM的基本原因很简单,你申请的内存多于系统可用量。我得说是虚拟内存,因为交换分区也包括在内。

了解OOM

开始了解OOM,首先试试这段会分配大量内存的代码:

#include <stdio.h>
#include <stdlib.h>

#define MEGABYTE 1024*1024

int main(int argc, char *argv[])
{
void *myblock = NULL;
int count = 0;

while (1)
{
myblock = (void *) malloc(MEGABYTE);
if (!myblock) break;
printf(”Currently allocating %d MBn”, ++count);
}

exit(0);
}

编译一下,运行它之后等一会。系统早晚会OOM。然后试试下面这段,分配大量内存并用1写入:

#include <stdio.h>
#include <stdlib.h>

#define MEGABYTE 1024*1024

int main(int argc, char *argv[])
{
void *myblock = NULL;
int count = 0;

while(1)
{
myblock = (void *) malloc(MEGABYTE);
if (!myblock) break;
memset(myblock,1, MEGABYTE);
printf(”Currently allocating %d MBn”,++count);
}
exit(0);

}

发现差别了么?A比B分配了更多内存。而且B被杀掉的更早一些。两个程序都因为没有可用内存而退出。更准确的说,A因为失败的malloc()而优雅的退出了,B是被OOM杀手干掉了。

首先观察分配的内存块数。假设你使用256M内存,888M交换分区(我的情况),B结束时:

Currently allocating 1081 MB

而A结束时:

Currently allocating 3056 MB

A怎么弄来的另外1975M?我骗人?没有!如果你仔细看,你会发现B用1填满得到的内存,而A几乎不拿他们干什么。Linux允许推迟的页分配, 换句话说,只当你真的要用的时候才开始分配动作,比如写入数据时。所以,除非写入数据,否则你可以一直要更多内存。术语称之为乐观的内存分配。

查看/proc/<pid>/status来确认信息。

$ cat /proc/<pid of program A>/status
VmPeak: 3141876 kB
VmSize: 3141876 kB
VmLck: 0 kB
VmHWM: 12556 kB
VmRSS: 12556 kB
VmData: 3140564 kB
VmStk: 88 kB
VmExe: 4 kB
VmLib: 1204 kB
VmPTE: 3072 kB

这是在B被杀之前的记录:

$ cat /proc/<pid of program B>/status
VmPeak: 1072512 kB
VmSize: 1072512 kB
VmLck: 0 kB
VmHWM: 234636 kB
VmRSS: 204692 kB
VmData: 1071200 kB
VmStk: 88 kB
VmExe: 4 kB
VmLib: 1204 kB
VmPTE: 1064 kB

VmRSS需要再详细点解释。RSS是Resident Set Size,也就是当前进程在内存中分配的块。也注意,在B到OOM之前已经用掉了几乎全部交换分区,而A根本没用。很明显malloc()除了保留内存之外什么也没做。

另外一个问题是:既然没有写页,为什么有3056M这个上限?这暴露出另外一个限制。在32位系统上,内存地址有4GB。其中0-3GB是用户使用,3-4GB为内核空间。

注意:有内核补丁可以实现全部分配4GB给用户空间,需要一些上下文切换的开销。

OOM的结论:

  1. VM中没有可用页。
  2. 没有足够的用户地址空间。
  3. 以上两者。

所以避免这些情况的策略是:

  1. 知道用户空间有多少。
  2. 知道可用页有多少。

当使用malloc()申请内存块时,你实际是要runtime的C库查看是否有预先分配的块可用。这个块尺寸至少应当和用户请求一样大。如果 有,malloc()会指派这个块给用户并标记为使用。否则malloc()必须通过扩展堆栈heap得到更多内存。所有申请的块都放在堆栈里。不要和 stack混淆,stack是用来存储本地变量和函数返回地址的。

Heap到底在哪里?可以看看进程地址映射:

$ cat /proc/self/maps
0039d000-003b2000 r-xp 00000000 16:41 1080084 /lib/ld-2.3.3.so
003b2000-003b3000 r-xp 00014000 16:41 1080084 /lib/ld-2.3.3.so
003b3000-003b4000 rwxp 00015000 16:41 1080084 /lib/ld-2.3.3.so
003b6000-004cb000 r-xp 00000000 16:41 1080085 /lib/tls/libc-2.3.3.so
004cb000-004cd000 r-xp 00115000 16:41 1080085 /lib/tls/libc-2.3.3.so
004cd000-004cf000 rwxp 00117000 16:41 1080085 /lib/tls/libc-2.3.3.so
004cf000-004d1000 rwxp 004cf000 00:00 0
08048000-0804c000 r-xp 00000000 16:41 130592 /bin/cat
0804c000-0804d000 rwxp 00003000 16:41 130592 /bin/cat
0804d000-0806e000 rwxp 0804d000 00:00 0 [heap]
b7d95000-b7f95000 r-xp 00000000 16:41 2239455 /usr/lib/locale/locale-archive
b7f95000-b7f96000 rwxp b7f95000 00:00 0
b7fa9000-b7faa000 r-xp b7fa9000 00:00 0 [vdso]
bfe96000-bfeab000 rw-p bfe96000 00:00 0 [stack]

这是cat实际的映射分布。你的结果可能不一样,取决于内核和调度的C库。最近的内核(2.6.x)都有标记,但是不能完全依赖这些标记。

Heap基本上是没有分配给程序映射和stack的自由空间,所以会缩小可用的地址空间,也就是3GB减去所有映射掉的部分。

How does the map for program A look when it can’t allocate more memory blocks? With a trivial change to pause the program (see loop.c and loop-calloc.c) just before it exits, the final map is:

当A不能分配内存块时看起来什么样子?对程序小小调整一下,暂停下来看看:

0009a000-0039d000 rwxp 0009a000 00:00 0 ---------> (allocated block)
0039d000-003b2000 r-xp 00000000 16:41 1080084 /lib/ld-2.3.3.so
003b2000-003b3000 r-xp 00014000 16:41 1080084 /lib/ld-2.3.3.so
003b3000-003b4000 rwxp 00015000 16:41 1080084 /lib/ld-2.3.3.so
003b6000-004cb000 r-xp 00000000 16:41 1080085 /lib/tls/libc-2.3.3.so
004cb000-004cd000 r-xp 00115000 16:41 1080085 /lib/tls/libc-2.3.3.so
004cd000-004cf000 rwxp 00117000 16:41 1080085 /lib/tls/libc-2.3.3.so
004cf000-004d1000 rwxp 004cf000 00:00 0
005ce000-08048000 rwxp 005ce000 00:00 0 ———> (allocated block)
08048000-08049000 r-xp 00000000 16:06 1267 /test-program/loop
08049000-0804a000 rwxp 00000000 16:06 1267 /test-program/loop
0806d000-b7f62000 rwxp 0806d000 00:00 0 ———> (allocated block)
b7f73000-b7f75000 rwxp b7f73000 00:00 0 ———> (allocated block)
b7f75000-b7f76000 r-xp b7f75000 00:00 0 [vdso]
b7f76000-bf7ee000 rwxp b7f76000 00:00 0 ———> (allocated block)
bf80d000-bf822000 rw-p bf80d000 00:00 0 [stack]
bf822000-bff29000 rwxp bf822000 00:00 0 ———> (allocated block)

六个虚拟内存区域VMA,反映出了内存请求。VMA是一组有相同访问权限的内存页,可以存在于用户空间的任意位置。

你现在会想,为什么是六个,而不是一个大区域?有两个原因。第一,一般很难在内存中找到这么大的“洞”。第二,程序不会一次申请所有的内存。所以glibc分配器可以在可用的页根据需要自由规划。

为什么我说是在可用的页?内存分配是以页的尺寸为单位的。这不是OS的限制,而是内存管理单元MMU的特性。页的尺寸不一定,一般x86平台是 4K。你可以通过getpagesize() 或者 sysconf() (_SC_PAGESIZE参数)获得。libc分配器管理所有页:分成较小的块,指派给进程,释放,等等。比如说,程序使用4097字节,你需要两个 页,尽管实际上分配器给你的在4105-4109字节之间。

使用256M内存,无交换分区的情况下,你有65536个可用页。对吗?不完全是。要知道一些内存区域被内核代码和数据占用,还有一些保留给紧急情况或者高优先的需求。dmesg可以显示这些信息:

$ dmesg | grep -n kernel
36:Memory: 255716k/262080k available (2083k kernel code, 5772k reserved,
637k data, 172k init, 0k highmem)
171:Freeing unused kernel memory: 172k freed

内核代码和数据在初始化时使用的init部分172K,之后会被内核释放。这样实际占用了2083 + 5772 + 637 = 8492字节。。实际的说,2123个页没有了。如果使用更多内核特性和模块,就会消耗更多。

另外一个内核的数据结构是页缓冲。页缓冲储存着读块设备的内容。缓冲的越多,可用的内存越少。不过如果系统内存不够,内核会回收缓冲占用的内存。

从内核和硬件的角度,以下非常重要:

  1. 不能保证分配的内存物理上连续;他们只是虚拟的连续。
    这个假象来自地址转换的方式。在保护模式环境,用户使用虚拟地址,而硬件使用物理地址。页目录和页表起到转换作用。比如说两个开始于0和4096的块实际上可能映射到1024和8192地址。

  2. 这样分配更容易。因为很难找到连续的块。内核将寻找满足需要的块而不是连续的块,也会调整页表使之看起来虚拟连续。
    这也有代价。因为内存块的不连续,有时CPU L1和L2的缓冲会欠满,虚拟连续的内存分散在不同的物理缓冲行,会减慢连续的内存访问。
    内存分配包括两步:第一步扩展内存区域的长度,然后根据需要分配页。这就是按需分页。在VMA扩展过程中,内核只检查请求是否和现有VMA重叠,范围是否在用户空间内。默认情况下,会忽略检查是否能进行实际的分配。
    所以,如果你的应用程序能请求并得到1G内存,而你只有16M加64Mswap也没什么奇怪。这种乐观的方式大家都满意。内核有对应的参数可以调整过度承诺。

  3. 有两种页类型:匿名页和文件页。当你在磁盘上mmap()一个文件就产生了文件页,匿名页来自malloc()。他们和文件无关。当内存紧张时,内 核会把匿名页交换出去并清空文件页。换句话说,匿名页会消耗交换分区。例外是,mmap()的文件有MAP_PRIVATE标签。这时文件的修尬只发生在 内存中。

    这些帮助你理解如何把swap当内存扩展。当然,访问一个页需要它回到内存里。

  
分配器内幕

实际的工作由glibc内存分配器完成。分配器把块交给程序,从内核的heap中去掉。

分配器就是经理,内核是工人。这样就能明白,最大的效率来自好的分配器而非内核。

glibc uses an allocator named ptmalloc. Wolfram Gloger created it as a modified version of the original malloc library created by Doug Lea. The allocator manages the allocated blocks in terms of “chunks.” Chunks represent the memory block you actually requested, but not its size. There is an extra header added inside this chunk besides the user data.
glibc使用ptmalloc作为分配器。Wolfram Gloger创造了这个修改版以替代Doug Lea的malloc。分配器使用chunk管理所有分配的块。chunk代表你实际申请的内存块,但不是那个尺寸。在块内部还有一个额外的头信息。

The allocator uses two functions to get a chunk of memory from the kernel:
分配器使用两个函数得到对应的内存chunk:

  • brk() 设置进程数据段的结尾。
  • mmap() 创建一个VMA,传递给分配器。

当然,malloc()只当当前池中没有chunk时才使用这些函数。

The decision on whether to use brk() or mmap() requires one simple check. If the request is equal or larger than M_MMAP_THRESHOLD, the allocator uses mmap(). If it is smaller, the allocator calls brk(). By default, M_MMAP_THRESHOLD is 128KB, but you may freely change it by using mallopt().
使用brk()或者mmap()需要一个简单的检查。如果请求大于等于M_MMAP_THRESHOLD,分配器使用mmap()。如果是小于,就使用brk()。默认情况下M_MMAP_THRESHOLD为128K,可以使用mallopt()调整。

在OOM情况下,ptmalloc如何释放内存是很有趣的。使用mmap()分配的块通过unmap()释放之后就完全释放了,使用brk()分配的块是 做释放标记,但是他们仍在分配器控制之下。如果另外一个malloc()请求尺寸小于等于自由chunk。分配器可以把多个连续的自由chunk合并,也 可以把它分割来满足要求。

这也就是说,一个自由chunk可能因为不能用来满足请求而被丢弃。失败的自由chunk合并也会加速OOM的产生。这也是糟糕的内存碎片的标志。

恢复

一旦发生了OOM,怎么办?内核会终止一个进程。为什么?这是唯一终止进一步请求内存的方法。内核不会假设进程有什么机制能自动终止,唯一的选择就是杀掉。

内核怎么知道改杀谁呢?答案在mm/oom_kill.c源码中。这个所谓的OOM杀手用函数badness()衡量现有进程的得分。得分最高的就是受害者。以下是评分标准:

  1. VM尺寸。这不是所有分配页的尺寸,而是进程拥有的所有VMA的总量。尺寸越大得分越高。
  2. 和一有关,子进程的VM尺寸也很重要。这个计数是累积的。
  3. 进程优先级小于0的(nice过的)得分高。
  4. 超级用户的进程被假设更重要,因而得分低。
  5. 进程运行时。时间越长得分越低。
  6. 进程进行直接硬件访问的可以免疫。
  7. swapper和init以及其他内核线程都免疫。

进程得分最高的赢得选举,然后被杀。

这个机制不完美,但是基本有效。标准一和二非常明确的表明VMA的尺寸的重要性,而不是实际页的数量。你可能觉得VMA尺寸也许会导致假警报,但是 其实不会。badness()调用发生在页分配函数中,当只有少数自由页而回收失败时,所以基本上这个值很接近进程拥有的页数。

为什么不数实际的页数呢?因为这样需要更多时间和更多锁,也导致快速判断的开销增大。所以OOM并不完美,也可能杀错。

内核使用SIGTERM信号通知目标进程关闭。

如何降低OOM风险

简单的规则:不要分配超出实际空闲的内存。然而,有很多因素会影响结果,所以策略要更精细一点儿:

通过有序的分配减少碎片

不需要高级的分配器。你可以通过有序的分配和释放减少碎片。使用LIFO策略:最后分配的最先释放。

比如以下代码:

void *a;
void *b;
void *c;
…………
a = malloc(1024);
b = malloc(5678);
c = malloc(4096);


………………….



free(b);
b = malloc(12345);

可以换成:

a = malloc(1024);
c = malloc(4096);
b = malloc(5678);
………………….


free(b);
b = malloc(12345);

这样,a 和c 两个chunk之间就不会有漏洞。你也可以考虑使用realloc()来调整已经产生的malloc()块的尺寸。

两个示例演示了这个影响。程序结束时会报告系统分配的内存字节数(内核和glibc分配器)以及实际使用的数量。例如,在2.6.11.1内核和glibc2.3.3.27上,不用参数fragmented1浪费了319858832 字节(约 305 MB) 而fragmented2 浪费了 2089200 字节 (越 2MB).152倍!

你可以进一步实验传递各种参数的结果。参数是malloc()的请求尺寸。

调整内核的overcommit行为

You can change the behavior of the Linux kernel through the /proc filesystem, as documented inDocumentation/vm/overcommit-accounting in the Linux kernel’s source code. You have three choices when tuning kernel overcommit, expressed as numbers in /proc/sys/vm/overcommit_memory:
你可以根据Documentation/vm/overcommit-accounting通过/proc目录的配置改变linux内核的行为。有三个选择:

  • 0意味着使用默认的模式判断是否overcommit。
  • 1意味着总是overcommit。 你现在应该知道有多危险了。
  • 2防止过度overcommit。可以调整/proc/sys/vm/overcommit_ratio. 最大的承诺值是swap + overcommit_ratio*MEM.

一般默认就够用了,但是模式2有更好的保护。相应的,模式2也需要你小心估计程序的需求。你肯定不想程序因为这个不能执行。当然这样也可以避免出现被杀掉。

分配内存后检查NULL指针,审计内存泄露

这是个简单的规则,但是容易被忽略掉。检查NULL可以知道分配器能够扩展内存区域,虽然不保证能分配需要的页。一般你需要担保或者推后分配,取决于情况。和overcommit配合, malloc()会因为认为不能申请自由页而返回NULL,从而避免了OOM。

内存泄露是不必要的内存消耗。应用程序将不再追踪泄露的内存块但是内核也不会回收,因为内核认为程序还在用。valgrind可以用来追踪这一现象。

总是查询内存分配统计

linux内核提供了/proc/meminfo来找到内存状态信息。top free vmstat的信息皆来于此。

你需要检查的是自由的和可回收的内存。自由不用解释,但什么是可回收的?这是指buffer和页cache。当内存紧张系统可以写回磁盘来回收。

$ cat /proc/meminfo
MemTotal: 255944 kB
MemFree: 3668 kB
Buffers: 13640 kB
Cached: 171788 kB
SwapCached: 0 kB
HighTotal: 0 kB
HighFree: 0 kB
LowTotal: 255944 kB
LowFree: 3668 kB
SwapTotal: 909676 kB
SwapFree: 909676 kB

基于以上输出,自由的虚拟内存为MemFree + Buffers + Cached + SwapFree

I failed to find any formalized C (glibc) function to find out free (including reclaimable) memory space. The closest I found is by using get_avphys_pages() or sysconf() (with the_SC_AVPHYS_PAGES parameter). They only report the amount of free memory, not the free + reclaimable amount.我不能找到一个正式的C函数来找出自由(含可回收)内存的空间。最接近的是get_avphys_pages() 或者 sysconf() (加 _SC_AVPHYS_PAGES 参数)他们只报告自由内存总量而不是自由加可回收。

这意味着为了精确的信息,你需要自己解析/proc/meminfo并计算。如果你懒,可以参考procps源代码。它包含ps top free工具。

关于其他内存分配器的实验

不同的分配器使用不同方法管理内存chunk。Hoard是一个例子。Emery Berger from the University of Massachusetts用它来进行高性能的内存分配。用于多线程程序,引入了每CPU heap的概念。

使用64位平台

需要使用更大用户地址空间的人可以考虑64位计算。内核不再使用3:1方式分割VM,因而对大于4G内存的机器也很合适

这个和扩展地址无关,比如INTEL的PAE,允许32位的处理器定址64G内存。这个是物理地址定址,跟用户无关。在虚拟地址部分用户仍然使用3GB。多余的内存可以访问,但是不是都可以映射到地址空间。不能映射的部分就不可用。

考虑在结构中使用打包的类型

Packed attributes can help to squeeze the size of structs, enums, and unions. This is a way to save more bytes, especially for array of structs. Here is a declaration example:打包的属性可以压缩struct enum 和 union的尺寸。这样对struct尤其可以节省

struct test
{
char a;
long b;
} __attribute__ ((packed));

这个招数在于它使各行不对齐,因而消耗了更多的CPU周期。对齐意味着变量的地址是数据类型的原本地址的整数倍。基于数据的访问频率,这样会更慢,但是考虑到排序和缓冲的相关性。

在用户进程使用ulimit() 

使用ullmit -v可以限制用户能mmap()的内存地址空间。到上限后,mmap(),以及malloc()会返回0因而OOM不会启动。对于多用户系统很有用,因为避免了乱杀无辜。



用cgroup限制内存以防止Linux因内存用尽卡死 用cgroup限制内存以防止Linux因内存用尽卡死 Linux在内存用尽的情况下,整个界面,包括tty和ctrl-alt-F1都会卡住难以响应。虽然Linux内核有OOM Killer机制杀掉吃内存的进程,但经常内存用尽时连OOM Killer都无法动作。 本篇讲述如何用cgroups限制内存防止整个Linux因内存用尽卡死。 因内存用尽卡住时怎么办 如果鼠标还能动一点,可以尝试在top中杀掉... 阅读详情

相关推荐

别再为FPGA程序裸奔发愁了!手把手教你用Quartus和AES256给Altera芯片上把‘锁’

本文详细介绍了如何为Altera/Intel FPGA芯片(如Cyclone系列)构建可靠的AES256加密体系,涵盖密钥类型选择、Quartus实操到JTAG链路验证的全流程。通过硬件级AES256引擎实现配置流解密,确保FPGA程序的安全保护,适用于工业控制器等高安全需求场景。

weixin_28309571的博客 389

嵌入式 linux启动时间优化

嵌入式 Linux 启动时间优化 2015年11月6日星期五 有些应用对系统启动时间有着特殊的要求。在很多场合下,这些系统并不需要针对所有任务立即就位,但是针对某些关键任务(例如接收以太网命令或者显示用户界面)则必须能够应对。该博文将提供一些方法和简单的步骤,在 ...

weixin_43138570的博客 1685

Conda换源全攻略:从清华源到默认源的保姆级切换教程(附常见问题解决)

本文提供Conda换源的完整教程,详细讲解如何从清华源切换到默认源,包括配置步骤、常见问题解决方案及高级技巧。针对国内开发者遇到的下载速度慢问题,清华源提供了高速稳定的解决方案,同时文章也介绍了恢复默认源的方法和多种镜像源选择。

weixin_28837817的博客 940

glibc 内存分配总结

1、下载和编译 源码下载:https://www.gnu.org/software/libc/ 下载后解压:tar zxvf glibc-2.23.tar.gz (原来这里下载了glibc-2.2.3.tar.gz,一个符号点之差,导致编译了半天不成功,各种错误) $ tar zxvf glibc-2.23.tar.gz $ mkdirglibc-build bin 设置环境变量bashrc cat bashrc export PATH=$PATH:/home/xxxx/mini_...

zz460833359的博客 1288

【人工智能AI】是什么?

人工智能(Artificial Intelligence),英文缩写为AI。它是研究、开发用于模拟延伸和扩展人的智能的理论方法技术及应用系统的一门新的技术科学。(百度百科)人工智能的基本原理:机器从「特定的」大量数据中总结规律,形成某些「特定的知识」,然后将这种「知识」应用到现实场景中去解决实际问题。在这个基本原理的基础上,有3个特征:1、人工智能本质上是一种工具2、人工智能技能只能解决特定的问题,而不是什么都能做3、人工智能属于归纳逻辑,可以告诉你是什么,但是不能告诉你为什么。

KJCZ.AK的博客 2万+

完整版:ultralytics下运行yoloworld并训练

本文介绍了Ultralytics YOLO环境的快速配置与使用流程:1) 通过conda创建Python 3.9环境并安装依赖包;2) 配置中科大镜像源加速安装PyTorch和Ultralytics;3) 准备YOLO格式数据集并修改data.yaml配置文件;4) 提供模型预测、训练和验证的常用指令,包括predict/train/val等命令参数设置。文章还包含CLIP模型下载、权重文件获取以及本地安装等注意事项,完整覆盖了从环境搭建到模型部署的全过程。

weixin_50209871的博客 1345

Linux内存分配小结--malloc、brk、mmap

http://blog.163.com/xychenbaihu@yeah/blog/static/132229655201210975312473/http://blog.sina.com.cn/s/blog_7c60861501015vkk.htmlLinux 的虚拟内存管理有几个关键概念: 1、每个进程都有独立的虚拟地址空间,进程访问的虚拟地址并不是真正的物理地址; 2、虚拟地址可通过每个进程上的页表(在每个进程的内核虚拟地址空间)与物理地址进行映射,获得真正物理地址; 3、如果虚拟地址对应物理地址

木牛的博客 1242

Origin2018(汉化版)在使用科学计数法的时候如何将坐标刻度的0.0改成0

文章目录1 问题2 解决方法 1 问题 先看下面这张图,当我使用科学计数法时,纵坐标出现了0.0的字样,这样看起来很不美观。有些期刊还会有要求,不能出现0.0的格式。 图1 那么该怎么将它改成0呢?首先让我们尝试着用Origin自带的属性,看看能不能设置。 2 解决方法 解决方法一: step1: 双击坐标轴,打开坐标轴属性设置。 step2: 在刻度线标签选项中设置左轴的显示 图2 会发现,按照图2的方式改好之后,其它的小数位也全没了,如果但是有些数字就被覆盖了,这显然不是我

qq_40077565的博客 2万+

mallopt()--控制 内存分配的函数

mallopt函数可以控制 内存分配的函数: int mallopt(int param,int value)//控制 内存分配的函数 。 param 的取值可以为M_CHECK_ACTION、M_MMAP_MAX、M_MMAP_THRESHOLD、M_MXFAST(从glibc2.3起)、M_PERTURB(从glibc2.4起)、M_TOP_PAD、M_TRIM_THRESHOLD

u013920085的专栏 2万+

深度学习流体力学:基于PyTorch的物理信息神经网络(PINN)完整实现

本文介绍了基于物理信息神经网络(PINN)的深度学习流体力学求解器实现。首先阐述了Navier-Stokes方程的理论基础,包括连续性方程和动量守恒方程,并解释了PINN的核心原理:将物理方程作为约束条件嵌入神经网络损失函数。以经典的lid-driven cavity流动为例,详细展示了使用PyTorch实现的全流程,包括神经网络架构设计、自动微分求解Navier-Stokes方程、多约束条件优化训练等关键环节。该求解器通过将物理方程、边界条件和初始条件整合到损失函数中,实现了对流体力学问题的端到端求解,为

源代码杀手的博客 9841

C#部署YOLO三种方案深度实测:OpenCV DNN vs ONNX Runtime vs TensorRT

在工业视觉项目落地阶段,C#生态下部署YOLO模型主要有三条技术路线。很多开发者仅凭经验选型,往往在部署后期踩中性能瓶颈、兼容故障、维护成本超标的坑。本文基于工控机常见硬件配置,针对YOLOv8系列模型做控制变量实测,从推理性能、部署难度、工业稳定性、综合成本等多个维度做横向对比,给出可直接落地的选型结论。

这里只有干货:从 Modbus 通信到 MES 对接,从 YOLO 训练到工控机部署,带你搞定工业软件开发全流程。 466

c linux new使内存耗尽_用cgroup限制内存以防止Linux因内存用尽卡死

Linux在内存用尽的情况下,整个界面,包括tty和ctrl-alt-F1都会卡住难以响应。虽然Linux内核有OOM Killer机制杀掉吃内存的进程,但经常内存用尽时连OOM Killer都无法动作。本篇讲述如何用cgroups限制内存防止整个Linux因内存用尽卡死。因内存用尽卡住时怎么办如果鼠标还能动一点,可以尝试在top中杀掉吃内存的进程。但这时想进入top并kill -9都很难。ctr...

weixin_39576270的博客 267

【归因】MATLAB实现最佳指纹法(待更新)

简述用于归因分析的最佳指纹法,及其MATLAB实现。

WW、forever的博客 4286

LINUX SWAP分区解疑——为什么物理内存没有用尽,就会产生SWAP

前段时间一直关注MYSQL服务器的交换分区使用情况,发现一种情况,即便物理内存仍有空余,仍会使用交换分区。查阅了很多相关资料,原因慢慢被挖掘出来。 首先,系统使用swap分区,并不意味着系统性能下降。这里分两种情况。 一种情况是:系统在检查系统物理内存使用情况时,发现有部分数据长期没有访问,此时,会发生swap,将这部分数据交换到swap分区中。 另一种情况是:应用程序在申请内存时,发现没有...

icquu的博客 2423

VB摄像头监控

该VB模块可对摄像头捕获的画面进行录像等,可在创建的窗口进行控制

visio安装包

Microsoft Office Visio 是一款专业的制图软件。利用经过更新的形状、协作工具和数据链接图表,创建专业级图表以简化复杂的信息。

linux free空闲内存用尽,Linux中显示空闲内存空间的free命令的基本用法

free 命令显示系统使用和空闲的内存情况,包括物理内存、交互区内存(swap)和内核缓冲区内存参数-b 显示内存的单位为字节-k 显示内存的单位为 KB-m 显示内存的单位为 M-o 忽略缓冲区调节列-t 总和信息-s 每隔指定时间执行一次命令,单位为s-h 以可读形式显示容量,需要free -V显示版本大于3.3-V 版本信息示例例1复制代码代码如下:root@tnak-VirtualBox:...

weixin_39819327的博客 280

pscad IEEE标准系统搭建说明

pscad IEEE标准系统搭建说明,包含典型的IEEE 9节点、14节点、30节点、39节点和118节点系统。内含标准测试系统的原始数据和潮流结果。

linux free空闲内存用尽,Linux free 命令 - 显示系统中空闲和已使用的内存

系统管理员必须维护他们服务器的健康运行。其中一个重要的部分就是内存。当服务器内存使用率过高时,它会降低服务器的性能。Linu系统管理员必须维护他们服务器的健康运行。其中一个重要的部分就是内存。当服务器内存使用率过高时,,它会降低服务器的性能。Linux有一个称为 free 的工具,来监控内存使用率。free 命令是什么free 命令是一个显示系统中空闲和已用内存大小的工具。free 命令的输出和 ...

weixin_34900758的博客 422

OV9734 DATASHEET,完整规格书

OV9734完整规格书,包括电气参数,尺寸规格,寄存器配置表等

linux free空闲内存用尽,Linux中显示空闲内存空间的free命令的基本用法,linuxfree...

Linux中显示空闲内存空间的free命令的基本用法,linuxfreefree 命令显示系统使用和空闲的内存情况,包括物理内存、交互区内存(swap)和内核缓冲区内存参数-b 显示内存的单位为字节-k 显示内存的单位为 KB-m 显示内存的单位为 M-o 忽略缓冲区调节列-t 总和信息-s 每隔指定时间执行一次命令,单位为s-h 以可读形式显示容量,需要free -V显示版本大于3.3-V 版本...

weixin_31188807的博客 509
上一篇: rpm包制作过程
下一篇: 修改centos stage2.img 文件
guowake
博客等级 码龄19年 62粉丝 66原创
评论
成就一亿技术人!
拼手气红包6.0元
还能输入1000个字符
 
 条评论被折叠 查看
添加红包

请填写红包祝福语或标题

个

红包个数最小为10个

元

红包金额最低5元

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

抵扣说明:

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

余额充值