我注意到这种奇怪的效果,其中内存未被Windows任务管理器分配,直到触摸它而不是它被malloc-ed或new-ed时.效果在debug优化的release构建中发生.
以下是一个结构示例,虽然在我的代码中,分配和利用发生在不同的线程上,所以我不认为它是优化器,虽然我不知道如何检查.
for (int i = 0 ;i < 1000;i++)
{
buffer[i]=malloc(buffersize);
}
_sleep(1000*60)
for (int i=0;i<1000;i++)
{
memset(buffer[i],0,buffersize);//Only shows up the in the resource manager here
}
Run Code Online (Sandbox Code Playgroud)
我的问题是Windows如何知道我使用了内存?它是监视内存以供第一次使用还是一些编译时优化.
我的好奇心是由于我正在编写的实时采集,需要我触摸内存两次 - >一次分配时,一次实际填充数据.因此,按下一个按钮("aquire!")需要我一次写入64千兆字节的ram,而不是随着时间的推移,增加了相当多的延迟.如果我malloc去,这会增加太多的延迟.
- 编辑 -
我还禁用了Windows页面文件...
共享对象(.so 文件)的代码(也称为 .text 部分)通常在进程之间共享。你可以在这里阅读它。
我写了一个小例子,其中事情似乎表现不同。
简而言之:程序证明对共享对象的代码部分所做的更改不会影响程序的其他实例。因此,共享对象的代码部分不在进程之间共享。
长解释:该代码由一个加载 .so 文件(mylib.c)的程序(main.c)组成。
该库由一个返回整数的函数组成。该整数与机器指令一起存储在代码段中。如果您不相信整数存储在代码部分中,您可以运行objdump -d libmy.so.
程序加载库,然后修改共享对象代码部分中的整数。在此之前,程序运行mprotect()以避免分段错误。该值正在更改为当前时间戳。
现在,我运行该程序两次,延迟 2 秒,因此每个实例都将其自己的值写入 .so 代码部分。令人惊讶的是,第一个实例的值没有被第二个实例的值覆盖。
这怎么可能?
我仅在 x64 上测试了该程序。只需保存文件并运行 bash 脚本即可。
libmy.c:
int getval()
{
return 123;
}
Run Code Online (Sandbox Code Playgroud)
主要.c:
#include <stdio.h>
#include <time.h>
#include <unistd.h>
#include <stdint.h>
#include <stdlib.h>
#include <sys/mman.h>
int getval();
void unprotect(uint64_t addr)
{
uint64_t pagesize = sysconf(_SC_PAGE_SIZE);
addr -= addr % pagesize;
if (mprotect((void*)addr, pagesize, PROT_READ | PROT_WRITE | PROT_EXEC) != 0)
{
printf("mprotect failed\n"); …Run Code Online (Sandbox Code Playgroud)