问题标签 [copy-on-write]

For questions regarding programming in ECMAScript (JavaScript/JS) and its various dialects/implementations (excluding ActionScript). Note JavaScript is NOT the same as Java! Please include all relevant tags on your question; e.g., [node.js], [jquery], [json], [reactjs], [angular], [ember.js], [vue.js], [typescript], [svelte], etc.

0 投票
3 回答
1336 浏览

linux - linux中的mprotect

如果我mprotect是一个带有 PROT_NONE 的段,并且如果 aSIGSEGV是由于由sigactionwith处理的写入而发生的sa_sigaction,我们将能够使用siginfo_t's找到发生故障的地址si_addr。但是有没有办法找到试图写入的数据和数据的长度?

我正在尝试这样做,因为我为我的项目尝试了一种写时复制机制。

0 投票
1 回答
842 浏览

kernel - 在禁用写时复制的情况下调用 do_fork

我正在做一个操作系统分配,它正在添加一个新的系统调用。称为“dumbfork”的系统调用需要在不使用写时复制策略的情况下分叉一个进程。所以基本上它必须将整个地址空间复制到子进程。

我能够设置和重新编译系统内核。我可以调用我的自定义系统调用,但我不知道如何实际实现哑叉来禁用 COW 功能。其中一个源代码向我展示了sys_vfork如何调用 do_fork。Dumbfork 应该类似于 sys_vfork。我不知道如何设置do_fork的参数。我试图模仿 sys_fork 是如何实现的,它给了我一个 NULL 指针取消引用错误。任何人都可以在这个问题上启发我。

0 投票
1 回答
2741 浏览

r - R:选择子集而不复制

有没有办法从对象(数据框、矩阵、向量)中选择一个子集而不复制所选数据?

我使用相当大的数据集,但从不更改它们。然而,为了方便起见,我经常选择要操作的数据子集。每次复制一个大子集的内存效率非常低,但是普通索引和subset(以及xapply()函数系列)都会创建所选数据的副本。所以我正在寻找可以克服这个问题的函数或数据结构。

一些可能适合我的需要并希望在某些 R 包中实现的方法:

  • 写时复制机制,即仅在您添加或重写现有元素时复制的数据结构;
  • 不可变数据结构,只需要为数据结构重新创建索引信息,而不是它的内容(比如通过只创建包含长度和指向同一个 char 数组的指针的小对象来从字符串中创建子字符串);
  • xapply()不创建子集的类似物。
0 投票
1 回答
839 浏览

c++ - 更有效地使用 fork() 和写时复制内存共享

我是一名程序员,使用基于 Linux 的服务器开发多人在线游戏。我们为我们的世界使用“实例化”架构。这意味着每个进入世界区域的玩家都会获得该区域的副本以与他们的党员一起玩,并且独立于在同一区域中玩的所有其他玩家。

在内部,我们为每个实例使用单独的进程。最初,每个实例进程都会启动,仅加载给定区域所需的资源,生成随机地形,然后允许来自玩家的新连接。一个实例使用的内存量通常约为 25 兆,包括资源和随机生成的实体级别。

为了减少实例的内存占用并加快生成时间,我们改为创建一个主实例来加载任何实例可能需要的所有资源(大约 150 兆内存),然后当需要一个新实例时,使用 fork() 函数生成一个新实例并利用写时复制内存共享,以便新实例只需要内存来存储它的“唯一”数据集。构成每个实例的唯一数据的随机生成的关卡和实体的占用空间约为 3-4 兆内存。

不幸的是,内存共享并没有我认为的那么好。很多内存页面似乎变得不共享。

起初,随着我们在 prefork 实例中加载更多数据集,每个 fork 实例所需的内存会下降,但最终会出现一个拐点,在 prefork 中加载更多资产实际上会增加每个 fork 实例使用的数据。

我们得到的最好结果是在分叉前加载大约 80 meg 的数据集,然后让新的实例按需加载其余部分。这导致每个实例大约增加 7-10 兆和 80 兆的固定成本。当然是一个很好的改进,但不是理论上最好的。

如果我加载整个 150 兆的数据集然后分叉,每个分叉的实例使用大约 50 兆的内存!比什么都不做要糟糕得多。

我的问题是,如何将我的所有数据集加载到 prefork 实例中,并确保我只获得每个实例真正唯一的最小数据集作为每个实例的内存占用。


我对这里发生的事情有一个理论,我想知道是否有人能够帮助我确认是这种情况。

我认为这与 malloc free 链有关。prefork 实例的每个内存页中可能都有一些空闲的内存点。如果在随机级别生成期间,分配的某些内容恰好适合页面中的一个空闲位置,那么整个页面将被复制到分叉进程中。

在 Windows 中,您可以创建备用堆,并更改进程使用的默认堆。如果这是可能的,它将消除问题。有没有办法在linux中做这样的事情?我的调查似乎表明你不能。

另一种可能的解决方案是,如果我能以某种方式丢弃现有的 malloc 空闲链,强制 malloc 从操作系统分配新内存以供后续调用。我试图查看 malloc 的实现,看看这是否容易实现,但似乎它可能有些复杂。如果有人对此领域有任何想法或建议从哪里开始使用这种方法,我很想听听。

最后,如果有人对这里可能出现的问题有任何其他想法,我真的很想听听他们的意见。非常感谢!

0 投票
2 回答
767 浏览

memory-management - 为什么在写入时复制时没有 SIGSEGV 信号?

wikipedia 上的写时复制文章说,写时复制通常是通过授予对页面的只读访问权限来实现的,因此当一个页面被写入时,页面错误陷阱处理程序可以为其映射一个唯一的物理内存页面。所以我的问题是为什么当这种页面错误发生时用户级应用程序没有收到 SIGSEGV 信号?毕竟,关于 SIGSEGV 的维基百科文章说 SIGSEGV 是当进程进行无效内存引用或分段错误时发送给进程的信号。所以在这种情况下,即写时复制的情况下,为什么没有 SIGSEGV 被发送到进程。

0 投票
3 回答
304 浏览

php - PHP null and copy-on-write

Suppose I want to have two variables and have them both equal to null. (More realistically, I am thinking about an array that contains a large amount of nulls, but the "two variables" scenario is sufficient for the question.) Obviously, I can do this in more than one way. I can do this (method 1):

#xA;

By my understanding, the result of this is that there is one zval that is pointed to by two entries in the symbol table: 'a' and 'b'. But alternatively one might do this (method 2):

#xA;

Naively one would expect that this should result in two different zvals, each pointed to by one entry in the symbol table.

Does it follow from this that if you want to have a large array, and many elements of the array will be null, it's more efficient (in terms of zval/memory use) to create a $master_null variable with the value null, and then write the null elements of the array by assigning using $master_null?

0 投票
2 回答
277 浏览

c - 查找哪些页面不再与写时复制共享

假设我在 Linux 中有一个进程,从中我有fork()另一个相同的进程。在forking 之后,由于原始进程将开始写入内存,Linux的写时复制机制将赋予该进程唯一的物理内存页,该物理内存页与分叉进程使用的内存页不同。

在执行的某个时刻,我如何知道原始进程的哪些页面已被写入时复制?

我不想使用 SIGSEGV 信号处理程序并在一开始就授予对所有页面的只读访问权限,因为这会导致我不想要的开销。

0 投票
1 回答
798 浏览

ruby - Ruby fork 是否对 COW 友好,如果是,如何测试它

我读过一些红宝石叉子友好的地方,好的链接

但是当我碰巧在谷歌上搜索更多信息时,我发现 Ruby 不支持COW(写入时复制)

现在我实际上有点困惑 ruby​​ 是否真的支持COW功能

我也知道REERubinius有一个COW 友好的 GC,所以我 REE 和 Rubinius 支持COW功能

我是的,我很想测试它,任何人都可以建议我,如果 ruby​​ 支持COW功能,那么如何编写示例代码来测试Ruby 中的 COW 概念

谢谢

0 投票
1 回答
1511 浏览

qt - Qt:可以使用QString作为异常类的成员吗

我正在开发一个自定义异常,我需要一个 QString 成员。就像是:

当我尝试使用它时:

我得到一个分段错误。症状与此处描述的相似: Qt QString cloning Segmentation Fault

SIGSEGV 源自QBasicAtomicInt::ref,来自QString::QString(const QString &other)

在我看来,好像有人试图在复制构造函数中复制无效的 QString。我的理解是,只要有对它的有效引用,QString 就会保留一个指向其内容的指针。如果正在制作 MyException 实例的副本,那么临时堆栈实例是否没有离开范围并且副本应该成功?

当我在MyException没有 QString 成员的情况下实现时,一切正常。

0 投票
1 回答
2377 浏览

c - 获取 fork()ing 的写时复制行为,无需 fork()

我有一个大缓冲区:

如果我派生了一个新进程,它将有一个与父进程共享内存的 buf,直到其中一个或另一个写入它。即使这样,内核也只需要分配一个新的 4KiB 块,其余的将继续共享。

我想制作一个 buf 的副本,但我只会更改一点副本。我想要不分叉的写时复制行为。(就像你在分叉时免费获得一样。)

这可能吗?