标签: virtual-memory

设置 /proc/sys/vm/drop_caches 以清除缓存

作为进行一些冷缓存计时的一部分,我正在尝试释放操作系统缓存。该内核文档(检索2019日)说:

drop_caches

Writing to this will cause the kernel to drop clean caches, as well as
reclaimable slab objects like dentries and inodes.  Once dropped, their
memory becomes free.

To free pagecache:
    echo 1 > /proc/sys/vm/drop_caches
To free reclaimable slab objects (includes dentries and inodes):
    echo 2 > /proc/sys/vm/drop_caches
To free slab objects and pagecache:
    echo 3 > /proc/sys/vm/drop_caches

This is a non-destructive operation and will not free any dirty objects.
To increase the number of objects freed …
Run Code Online (Sandbox Code Playgroud)

linux virtual-memory

104
推荐指数
1
解决办法
21万
查看次数

从 /proc/pid/smaps 获取有关进程内存使用情况的信息

对于 中的给定进程/proc/<pid>/smaps,对于给定的映射条目是:

  1. Shared_Clean
  2. Shared_Dirty
  3. Private_Clean
  4. Private_Dirty

Shared_Clean+Shared_Dirty是与其他进程共享的存储器的量?所以它就像共享RSS?

同样是Private_Clean+仅可用于一个进程Private_Dirty的内存量?所以它就像私人RSS?

PSS 值是否 = PrivateRSS +(SharedRSS / 共享它的进程数)?

阅读此链接后还有一些问题:LWN

现在让我们从整体上讨论这个过程,我们正在查看其 smaps 条目。

我注意到,如果我为流程的每个 smaps 条目执行Shared_Clean+ Shared_Dirty+ Private_Clean+ Private_Dirty,我会得到流程的 RSS 报告ps,这非常酷。例如

ps -p $$ -o pid,rss
Run Code Online (Sandbox Code Playgroud)

将为我提供与/proc/$$/smaps中每个Shared_Clean, Shared_Dirty, Private_Clean,Private_Dirty条目的总和(大约)相同的 rss 值。

但是整个过程的PSS呢?那么,从上面的示例中,我如何获得 $$ 的 PSS?我可以为每个 smaps 映射添加 PSS 条目并以 $$ 到达 PSS 吗?

那么整个过程中的USS …

linux process memory virtual-memory

55
推荐指数
1
解决办法
6万
查看次数

为什么在错误的“rm”保存我的文件后关闭我的机器?

经典情况:我跑得不好rm,之后立即意识到我删除了错误的文件。(没什么重要的,我最近的备份还算可以,但还是很烦人。)

知道如果我想使用extundelete或此类工具恢复文件,进一步的磁盘活动是我的敌人,我立即关闭了机器的物理电源(即,使用电源按钮,而不是使用halt或任何此类命令)。这是一台没有运行重要任务或任何打开的笔记本电脑,所以这是一个可以接受的操作。(顺便说一下,从那时起我了解到在这种情况下要做的第一件事是首先估计丢失的文件是否仍然可以被进程打开https://unix.stackexchange.com/a/101247 --如果是,您应该通过这种方式恢复它们,而不是关闭机器。)

尽管如此,一旦机器断电,我想了一会儿,并认为这些文件不值得花时间启动实时系统进行适当的取证。所以我重新启动了机器。然后我发现我的文件仍然位于磁盘上:rm在我关闭电源之前还没有传播到磁盘。我跳了一小段舞,感谢系统管理员之神出人意料的宽恕。

我现在的问题是要了解这是如何可能的,以及rm实际传播到磁盘之前的典型延迟是多少。我知道磁盘 IO 不会立即刷新,而是在内存中停留了一段时间,但我认为磁盘日志会很快确保挂起的操作不会完全丢失。https://unix.stackexchange.com/a/78766似乎暗示了一种单独的机制来刷新脏页和刷新日志操作,但没有提供足够的细节来说明日志将如何参与 arm以及之前的预期延迟操作被刷新。

更多细节:数据位于 LUKS 卷内的 ext4 分区中,在启动机器备份时,我看到以下内容syslog

Sep 24 10:24:58 gamma kernel: [   11.457007] EXT4-fs (dm-0): 1 orphan inode deleted
Sep 24 10:24:58 gamma kernel: [   11.458393] EXT4-fs (dm-0): recovery complete
Sep 24 10:24:58 gamma kernel: [   11.482475] EXT4-fs (dm-0): mounted filesystem with ordered data mode. Opts: (null)
Run Code Online (Sandbox Code Playgroud)

但我不相信它与rm.

另一个问题是是否有办法告诉内核不要执行任何挂起的磁盘操作(而是将它们转储到某处),而不是关闭机器电源。(当然,不执行挂起的操作听起来很危险,但这就是在关闭机器电源时会发生的情况,并且在某些情况下它可以拯救您。)当然,这将是“更干净”,也很有趣例如,对于物理断电不是一个简单选择的远程服务器。

data-recovery rm journaling virtual-memory linux-kernel

33
推荐指数
1
解决办法
2471
查看次数

Linux 不使用分段而只使用分页吗?

Linux 编程接口显示了进程的虚拟地址空间的布局。图中的每个区域都是一个段吗?

在此处输入图片说明

了解 Linux 内核

下面的意思是MMU中的分段单元将段和段内的偏移量映射到虚拟内存地址,然后分页单元将虚拟内存地址映射到物理内存地址是否正确?

内存管理单元(MMU)通过称为分段单元的硬件电路将逻辑地址转换为线性地址;随后,称为分页单元的第二个硬件电路将线性地址转换为物理地址(见图 2-1)。

在此处输入图片说明

那为什么说Linux不使用分段而只使用分页呢?

分段已包含在 80x86 微处理器中,以鼓励程序员将他们的应用程序拆分为逻辑相关的实体,例如子程序或全局和本地数据区。但是, Linux 以非常有限的方式使用分段。实际上,分段和分页是有些多余的,因为两者都可以用来分隔进程的物理地址空间:分段可以为每个进程分配不同的线性地址空间,而分页可以将相同的线性地址空间映射到不同的物理地址空间. 出于以下原因,Linux 更喜欢分页而不是分段:

• 当所有进程使用相同的段寄存器值时,即当它们共享同一组线性地址时,内存管理更简单。

• Linux 的设计目标之一是可移植到广泛的体系结构中。特别是 RISC 体系结构对分段的支持有限。

2.6 版本的 Linux 仅在 80x86 架构需要时才使用分段。

linux kernel virtual-memory

33
推荐指数
4
解决办法
9242
查看次数

这是 Linux 分页的行为方式吗?

当我的 Linux 系统接近分页时(即,在我的情况下,16GB ram 几乎已满,16GB 交换完全空),如果新进程 X 尝试分配一些内存,系统将完全锁定。也就是说,直到不成比例的页面数量(与 X 的内存分配请求的总大小和速率)被换出。请注意,不仅 gui 变得完全没有响应,而且甚至像 sshd 这样的基本服务也完全被阻止。

这是我用来以更“科学”的方式触发这种行为的两段代码(诚然粗糙)。第一个从命令行获取两个数字 x,y 并继续分配和初始化多个 y 字节块,直到分配的总字节数超过 x 为止。然后无限期地睡觉。这将用于使系统处于寻呼的边缘。

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

int main(int argc, char** argv) {
   long int max = -1;
   int mb = 0;
   long int size = 0;
   long int total = 0;
   char* buffer;

   if(argc > 1)
     {
       max = atol(argv[1]);
       size = atol(argv[2]);
     }
   printf("Max: %lu bytes\n", max);
   while((buffer=malloc(size)) != NULL && total < max) {
       memset(buffer, …
Run Code Online (Sandbox Code Playgroud)

kernel swap virtual-memory

26
推荐指数
1
解决办法
937
查看次数

进程的实际内存使用情况

以下是我服务器上mysql和的内存使用情况apache。根据pmapsay的输出,mysql正在使用大约 379M,apache正在使用 277M。

[root@server ~]# pmap 10436 | grep total
 total           379564K

[root@server ~]# pmap 10515 | grep total
 total           277588K
Run Code Online (Sandbox Code Playgroud)

将其与 的输出进行比较top,我发现值几乎匹配。

  PID USER      PR  NI  VIRT  RES  SHR S %CPU %MEM    TIME+  COMMAND
10515 apache    20   0  271m  32m 3132 S  0.0  6.6   0:00.73 /usr/sbin/httpd
10436 mysql     20   0  370m  21m 6188 S  0.0  4.3   0:06.07 /usr/libexec/mysqld --basedir=....
Run Code Online (Sandbox Code Playgroud)

现在这些值绝对不是这两个进程的当前内存使用情况,因为如果是的话,它会超过ram我系统上的 512M ,我明白这些是分配给这两个进程的页面大小的事实,而不是真的他们积极使用的内存大小。现在,当我们使用 时pmap -x …

memory virtual-memory

25
推荐指数
2
解决办法
11万
查看次数

为什么 Debian Linux 允许每个进程最多 128TiB 的虚拟地址空间,但只允许 64TiB 的物理内存?

我刚在这里读到:

  • 每个进程最多 128TiB 虚拟地址空间(而不是 2GiB)
  • 64TiB 物理内存支持而不是 4GiB(或 64GiB 与 PAE 扩展)

这是为什么?我的意思是,物理内存支持受到内核或当前硬件的限制?

为什么您需要的虚拟内存空间是实际可寻址的物理内存的两倍?

debian virtual-memory linux-kernel

23
推荐指数
3
解决办法
4127
查看次数

Linux 会“耗尽 RAM”吗?

我在网上看到一些帖子,显然有人抱怨托管 VPS 意外杀死进程,因为他们使用了过多的 RAM。

这怎么可能?我认为所有现代操作系统都通过对物理 RAM 上的任何内容使用磁盘交换来提供“无限 RAM”。这样对吗?

如果一个进程“由于内存不足而被杀死”,可能会发生什么?

linux kernel swap virtual-memory ram

21
推荐指数
3
解决办法
1万
查看次数

堆栈分配在 Linux 中是如何工作的?

操作系统是否为堆栈或其他东西保留了固定数量的有效虚拟空间?我是否能够仅通过使用大局部变量来产生堆栈溢出?

我写了一个小C程序来测试我的假设。它在 X86-64 CentOS 6.5 上运行。

#include <string.h>
#include <stdio.h>
int main()
{
    int n = 10240 * 1024;
    char a[n];
    memset(a, 'x', n);
    printf("%x\n%x\n", &a[0], &a[n-1]);
    getchar();
    return 0;
}
Run Code Online (Sandbox Code Playgroud)

运行程序给出&a[0] = f0ceabe0&a[n-1] = f16eabdf

proc 映射显示堆栈: 7ffff0cea000-7ffff16ec000. (10248 * 1024B)

然后我尝试增加 n = 11240 * 1024

运行程序给出&a[0] = b6b36690&a[n-1] = b763068f

proc 映射显示堆栈: 7fffb6b35000-7fffb7633000. (11256 * 1024B)

ulimit -s10240在我的电脑上打印。

如您所见,在这两种情况下,堆栈大小都大于ulimit -s给出的大小。并且堆栈随着更大的局部变量而增长。堆栈顶部以某种方式减少了 3-5kB &a[0](AFAIK,红色区域为 128B)。

那么这个堆栈映射是如何分配的呢?

linux memory virtual-memory stack

20
推荐指数
2
解决办法
2万
查看次数

如何增加 Mac OS X 上的最大交换空间?

在 Mac OS X Yosemite 10.10.5 上,当我尝试运行需要分配和使用 128 GB 内存的计算(它是一个用 C 编写的命令行程序)时,内核以极端的偏见杀死了我的进程。此控制台日志条目是一个实例的示例:

15 年 9 月 25 日 7:08:40.000 PM 内核 [0]:低交换:杀死 pid 6202 (huffgrp)

当它分配和使用 64 GB 内存时,计算工作正常并且在合理的时间内。我的 Mac 有 32 GB 的 RAM 和硬盘驱动器上的 Beaucoup 空间。我也在另一台具有 8 GB RAM 的 Mac 上尝试过这个,64 GB 的计算也运行良好,当然需要更长的时间,但 128 GB 的计算以相同的方式被内核杀死。

顺便说一句,malloc()无论我要求多少空间,都永远不会返回错误。内核只会在进程实际使用过多内存时终止该进程,从而导致大量交换到硬盘驱动器。

所以似乎有一个秘密交换空间限制在 64 GB 和 128 GB 之间。

我的问题是:如何重新配置​​内核以允许更多交换空间?我找到了一个很有前途的文件,/System/Library/LaunchDaemons/com.apple.dynamic_pager.plist但我没有看到里面的秘密号码。手册页dynamic_pager说它所做的只是设置交换文件的名称和位置。同一个手册页有一个旧版本,它记录了一个-S选项来设置创建的交换文件的大小。我试过了,请求 160 GB 交换文件,但没有效果。每个交换文件仍然是 1 GB,并且该进程仍然被内核杀死。

osx configuration swap virtual-memory darwin

16
推荐指数
1
解决办法
2万
查看次数