标签: virtual-memory

如何从SEGV恢复

我有大量的数据存储在一个文件中.这个文件是mmap,但我随时只访问少量数据.我想了解我的程序的访问模式,以便我可以优化数据的排序(以便经常访问数据被分组到相同的页面中).目标是减少mmaped文件的工作集.

所以,我正在考虑使用R/W映射文件禁用.每次读/写尝试都会导致SEGV.在我的SEGV处理程序中,我将记录访问地址并允许程序继续.

我可以在错误地址处解码指令,并模拟其动作(通过相应地修改目标寄存器和存储器位置).

但是,我在某处读到Linux无法从SEGV中恢复.这是真的?当我的信号处理程序被调用时,我如何向操作系统表明"一切都很好,请在故障指令后立即继续"?

请注意,我不希望它重做错误指令,因为我会模拟它.

我现在只关心x86/x64架构.

谢谢!

trace signals mmap virtual-memory

6
推荐指数
0
解决办法
3429
查看次数

是否有关于"社交网络"中询问的分页qn的解释?

"假设您的计算机具有16位虚拟地址和256字节的页面大小.系统使用从地址十六进制400开始的1级页表.也许您想要DMA ...谁知道?前几个页面保留用于硬件标志等.假设页表条目有8个状态位.8个状态位将是......"

http://www.youtube.com/watch?v=-3Rt2_9d7Jg

有人可以解释为什么答案是马克/杰西描述的吗?

paging operating-system virtual-memory

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

当我使用 VirtualAlloc() 和 MEM_RESERVE 保留内存时,我是否应该能够在 64K 边界上增加我的分配?

首先,我非常清楚如何VirtualAlloc()工作:当我保留内存块时,我得到与 64K 边界对齐的地址(可以通过 轻松获得该值GetSystemInfo()),然后当我提交页面时,我得到它们的页面大小边界,通常为 4K。

我无法得到的事情是,为什么如果我使用标志调用VirtualAlloc()MEM_RESERVE所以我要保留页面)并且指定一定的大小,比如说 4096,那么我将无法将该区域进一步增长到 64K ?

我的意思是:当我提交页面时,我可以使用最多 4K 的内存,因为 Windows 会将这些提交与页面大小对齐(当然,我正在提交页面!),但是当我保留内存区域时,应该Windows 不会将我传递到的区域大小调整VirtualAlloc()为 64K 吗?“浪费”的 15 页都去哪儿了?

因此,如果我保留 4096 字节,我是否应该能够提交更多页面直到 65536 字节?看来并非如此,因为如果我尝试这样做,VirtualAlloc()则会因ERROR_INVALID_ADDRESS最后一个错误代码而失败。

但为什么?如果 Windows 确实在 64K 边界上保留页面,并且我保留小于该大小的页面,我会永远丢失不保留的页面吗?因为似乎没有办法再次提交它们,或者调整区域大小以适应我因较低的预留而错过的 64K 边界。

那么,进程的虚拟空间会不会有漏洞呢?为了避免这种情况,我是否必须始终在 64K 边界上保留内存,因此在保留页面时始终VirtualAlloc()给出64K 对齐的值?

当我使用的时候呢MEM_RESERVE|MEM_COMMIT?由于标志的原因,我不应该在那里传递 64K 对齐的大小吗MEM_RESERVE

我提供了一些我尝试过的代码示例。正如您在这里所看到的,第一个函数成功了,因为我保留了更多页面,那么我的提交将有足够的“保留区域”来实际提交,在这种情况下,该区域将<64K,那么那些“丢失的”页面去哪儿了?

在第二种情况下,我只是MEM_RESERVE|MEM_COMMIT,因此提交其他页面会失败并显示ERROR_INVALID_ADDRESS最后一个错误代码。很公平,但同样在这里,为什么我不能提交更多页面,至少在 64K 边界上?为了不浪费地址并创建这些“漏洞”,我真的应该在 64K 边界上保留虚拟内存吗?如果我不遵守这个原则怎么办?我总是看到很多代码只是简单地VirtualAlloc()MEM_COMMIT|MEM_RESERVE …

c++ winapi memory-management allocation virtual-memory

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

如何使用保留的CMA内存?

我想为具有DMA支持的设备分配一块物理连续的保留内存(在预定义的物理地址中)。如我所见,CMA具有三个选项:1.通过内核配置文件保留内存。2.通过内核cmdline保留内存。3.通过设备树内存节点保留内存。在第一种情况下:可以保留区域的大小和数量。

CONFIG_DMA_CMA=y
CONFIG_CMA_AREAS=7
CONFIG_CMA_SIZE_MBYTES=8
Run Code Online (Sandbox Code Playgroud)

所以我可以使用:

start_cma_virt = dma_alloc_coherent(dev->cmadev, (size_t)size_cma, &start_cma_dma, GFP_KERNEL);
Run Code Online (Sandbox Code Playgroud)

在我的驱动程序中分配连续的内存。我最多可以使用7次,最多可以分配8M。但遗憾的是

dma_contiguous_reserve(min(arm_dma_limit, arm_lowmem_limit));
Run Code Online (Sandbox Code Playgroud)

从arch / arm / mm / init.c:

void __init arm_memblock_init(struct meminfo *mi,const struct machine_desc *mdesc)
Run Code Online (Sandbox Code Playgroud)

不可能为连续分配设置预定义的物理地址。当然我可以使用内核cmdline:

mem=cma=cmadevlabel=8M@32M cma_map=mydevname=cmadevlabel
//struct device *dev = cmadev->dev; /*dev->name is mydevname*/
Run Code Online (Sandbox Code Playgroud)

之后,dma_alloc_coherent()应该在物理内存区域中从32M + 8M(0x2000000 + 0x800000)到0x27FFFFF分配内存。但不幸的是,我对此解决方案有疑问。也许我的cmdline有错误?下一个尝试是设备树实现。

cmadev_region: mycma {
    /*no-map;*/ /*DMA coherent memory*/
    /*reusable;*/
    reg = <0x02000000 0x00100000>;      
};
Run Code Online (Sandbox Code Playgroud)

并在某些节点中:

memory-region = <&cmadev_region>;
Run Code Online (Sandbox Code Playgroud)

正如我通常在内核中看到的那样,应将其使用为:

of_find_node_by_name(); //find needed node
of_parse_phandle(); //resolve a phandle property to a device_node pointer
of_get_address(); //get DT __be32 …
Run Code Online (Sandbox Code Playgroud)

memory-management virtual-memory linux-device-driver linux-kernel device-tree

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

为什么 64 位 cpu 不存在高内存?

当我试图了解 32 位 cpu 和 Linux 的高内存问题时,为什么64 位 cpu没有高内存问题

特别是虚拟内存的内核空间和用户空间的划分是如何变化的,使得64位cpu不存在高内存的需求?

谢谢。

linux cpu-architecture virtual-memory

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

多线程 mprotect 的行为

出于并发/并行 GC 的目的,我对 mprotect 系统调用提供的内存顺序保证感兴趣(即 mprotect 多线程的行为或 mprotect 的内存模型)。我的问题是(假设没有编译器重新排序或有足够的编译器障碍)

  1. 如果线程 1 由于线程 2 上的 mprotect 而触发地址上的段错误,我能否确定在线程 1 中的段错误信号处理程序中可以观察到系统调用之前,一切都发生在线程 2 上?如果在线程 1 上执行加载之前在信号处理程序中放置了一个完整的内存屏障怎么办?

  2. 如果线程 1 在线程 2 设置为 PROT_NONE 的地址上执行易失性加载并且没有触发段错误,那么这是否足以在两者之间发生关系之前发生。或者换句话说,如果两个线程都这样做(*ga开始为0p是一个以只读方式开始的页面对齐地址)

    // thread 1
    *ga = 1;
    *(volatile int*)p; // no segfault happens
    
    // thread 2
    mprotect(p, 4096, PROT_NONE); // Or replace 4096 by the real userspace-visible page size
    a = *ga;
    
    Run Code Online (Sandbox Code Playgroud)

    是否可以保证a在线程 2 上会出现1?(假设在线程 1 上没有观察到段错误并且没有其他代码修改*ga

我最感兴趣的是 Linux 行为,尤其是 …

c multithreading garbage-collection mprotect virtual-memory

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

使用端口映射I/O时是否使用虚拟内存?

如果我有一个内存映射的I/O设备,并且我想写入位于0x16D340x16D34地址的该设备的寄存器,该地址实际上是一个虚拟地址,CPU将首先将其转换为物理地址,然后写入数据到物理地址.

但对于端口映射I/O设备(例如:串行端口),所以如果我想要写一个寄存器位于地址串口0x3F8,是0x3F8地址的物理地址或虚拟地址?


编辑:我在x86架构上.

c linux x86 device-driver virtual-memory

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

C# - 如何判断系统是否有虚拟内存/页面文件?

我有一个应用程序,它消耗了我部署给用户的大量 RAM。我的一些用户在运行它时遇到内存不足的异常 - 我注意到这是因为他们关闭了他们的系统页面文件(因为现在谁会使用 16GB 的内存?叹息......)。我想检测用户是否已将其设置为关闭(或者可能是其他一些设置),以便我可以警告他们,因为我们有很多用户来找我们寻求支持,我想自动化一些用户,因为他们正在吃饭占用了我们很多时间。

我在谷歌上搜索,似乎找不到获取有关页面文件信息的方法。具体来说,我说的是您可以在此页面中在 windows 中看到的信息: windows中的页面文件设置

我知道这是我们的最终用户问题,与我们的应用程序无关(我们的应用程序旨在占用大量内存并获得显着的速度优势)。我不确定如何检测这些类型的设置 - 有没有人知道?

c# wmi virtual-memory

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

缓存提供的空间局部性是指虚拟内存、物理内存还是两者兼而有之?

我试图理解为什么可以以某种方式编写使用数组(例如矩阵乘法)的程序来利用缓存的空间局部性。

  • 缓存提供的空间局部性是指虚拟内存、物理内存或两者中的局部性吗?当计算机系统将一块数据从主内存带入 CPU 缓存时,它是否将虚拟或物理上连续的数据对象带入 CPU 缓存?

  • 当我们以非动态方式或动态方式(通过 malloc())定义一个数组或结构对象时,连续分配这样的数组或对象是否正确?“连续”是指虚拟内存还是物理内存或两者兼而有之?

如果缓存的空间局部性是用于物理内存而不是虚拟内存,并且操作系统可以分配给 C 程序实际上不一定是物理连续的数组,那么我们如何编写程序来利用缓存的空间局部性?

谢谢。

c malloc caching virtual-memory

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

虚拟地址空间

我已经开始了解虚拟地址空间(VAS),我有几个问题:

  1. 根据架构(32 位和 64 位),为每个进程创建多少 VAS?
  2. 每个进程的VAS都是在硬盘上创建的吗?如果是这样,如果空间不足怎么办?
  3. VAS 和虚拟内存 (VM) 有什么区别?

linux memory-management process virtual-memory virtual-address-space

6
推荐指数
2
解决办法
3732
查看次数