问题标签 [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.
memory - 如何判断内存页是否被标记为只读?
当使用写时复制语义在进程之间共享内存时,如何测试内存页是否可写或是否标记为只读?这可以通过调用特定的汇编代码、读取内存中的某个位置或通过操作系统的 API 来完成吗?
optimization - 什么是写时复制?
我想知道什么是写时复制以及它的用途。Sun JDK 教程中多次提到该术语。
c++ - 为什么 VC++ 字符串不被引用计数?
STL 标准不要求从 std::string 被引用。但事实上,大多数 C++ 实现都提供了引用计数、写入时复制的字符串,允许您将字符串作为原始类型按值传递。此外,这些实现(至少 g++)使用原子操作使这些字符串无锁且线程安全。
简单的测试显示了写时复制语义:
在使用非常量成员之后,仅打印两个地址。
我使用 HP、GCC 和 Intel 编译器测试了这段代码,得到了类似的结果——字符串作为写时复制容器工作。
另一方面,VC++ 2005 清楚地表明每个字符串都是完全复制的。
为什么?
我知道 VC++6.0 中有一个错误,它具有非线程安全的引用计数实现,导致随机程序崩溃。这是原因吗?他们只是害怕再使用引用计数,即使这是常见的做法?他们宁愿完全不使用引用计数来解决问题?
谢谢
python - 写时复制的纯功能数据结构?
我想拥有功能数据结构(可以共享结构的多个数据版本)的优势,但能够以命令式的方式对其进行修改。
我在想什么(以及可能的用途):一个 RPG 游戏,其中存储了整个游戏历史(例如,允许时光倒流)。使用写时复制,我可以简单地克隆保存游戏状态的结构并通过引入新回合来修改它 - 但可以访问早期的回合(不一定是所有回合,可能只是选择的游戏状态快照),没有每次都必须复制所有内容的惩罚。
假设foo
是一张地图。
没有任何foo
结构(例如,树)被复制。但是,从现在开始bar
被视为副本,不允许任何更改传播回 `foo'。
现在
- 创建了一个新对象,即
baz
. bar
被替换为新地图,持有新地图baz
(可能保留一些foo
's 结构)。foo
不受影响。
但如果我们这样做...
...baz
可以只修改,因为我们有它的最新版本。bar
不需要改变。
foo
所有这些都需要保存一些关于and的版本信息bar
,在 上增加它foo.clone()
,并以某种方式传递它baz
(通过使其成为代理对象?)。
此外,已克隆的结构的任何部分都将成为“历史的一部分”并且不能再更改,这可以在运行时强制执行。
这有点类似于 JavaScript 的原型,但我更像是因为它允许更改向上传播。我认为它类似于版本控制系统。
- 有没有做到这一点,做到什么程度?
- 这是一个好主意吗?如果没有,有没有办法挽救它?
- 如何实施?我正在考虑在一些高级 GC 语言(如 Python)之上构建它。
c++ - 如何实现写时复制?
我想在我的自定义 C++ String 类上实现写时复制,我想知道如何...
我尝试实现一些选项,但结果都非常低效。
感谢你们 :-)
c++ - Why is there no boost::copy_on_write_ptr?
I just saw this nice copy-on-write pointer implementation. It looks pretty generic and useful, so my question is: Is such a class contained in any of the C++ toolkits (boost, loki, etc.)? If not, I'd really like to know why because it is a really useful idiom and apparently a generic implementation seems doable (like the one I linked to).
c++ - Qt 未记录的方法 setShareable
我偶然发现了一种似乎存在于所有数据对象中的方法,例如QList
, QQueue
, QHash
...
我什至调查到目前为止我可以看到它的源代码,即
在qlist.h中(第 117 行)。
但它对QList
, QQueue
, QHash
... 有什么影响?它是否与线程相关(这听起来很合理)?
感谢您的任何回答,请仅在您有实际知识的情况下回答。
linux - How to check if the block is present in a sparse file (for simple copy-on-write)?
How to get sparse block size and check if data is present at the given offset in sparse file in reiserfs/ext3 in Linux?
I want to use it to implement simple copy-on-write block device using FUSE.
Or I should better keep a bitmap in a separate file?
linux-kernel - 为什么 COW mmap 在大于 4GB 的(稀疏)文件上使用 ENOMEM 失败?
当尝试使用写时复制语义(PROT_READ | PROT_WRITE 和 MAP_PRIVATE)映射 5GB 文件时,会在 2.6.26-2-amd64 Linux 内核上发生这种情况。映射小于 4GB 的文件或仅使用 PROT_READ 可以正常工作。这不是本问题中报告的软资源限制问题;虚拟限制大小是无限的。
这是重现问题的代码(实际代码是Boost.Interprocess的一部分)。
这就是发生的事情:
这是相关的 strace (新编译的 4.5.20)输出,正如 nos 所要求的那样。
.net - 调用 ToString 后,StringBuilder 是否变得不可变?
我清楚地记得在 .NET 的早期,在 StringBuilder 上调用 ToString 用于为新字符串对象(要返回)提供 StringBuilder 使用的内部字符缓冲区。这样,如果您使用 StringBuilder 构造了一个巨大的字符串,调用 ToString 就不必复制它。
在这样做时,StringBuilder 必须防止对缓冲区进行任何额外的更改,因为它现在被一个不可变的字符串使用。结果,StringBuilder 将切换到“更改时复制”,其中任何尝试的更改都将首先创建一个新缓冲区,将旧缓冲区的内容复制到它,然后才对其进行更改。
我认为假设是 StringBuilder 将用于构造一个字符串,然后转换为常规字符串并丢弃。对我来说似乎是一个合理的假设。
现在事情就是这样。我在文档中找不到任何提及。但我不确定它是否被记录在案。
所以我查看了使用 Reflector (.NET 4.0) 的 ToString 的实现,在我看来它实际上是复制字符串,而不是仅仅共享缓冲区:
现在,正如我之前提到的,我清楚地记得读过早期的 .NET 就是这种情况。我什至在这本书中找到了提及。
我的问题是,这种行为是否被放弃了?如果是这样,有人知道为什么吗?这对我来说很有意义......