标签: memory-mapped-files

系统错误0x5:CreateFileMapping()

我希望使用命名共享内存来实现IPC.

为此,其中一个步骤是使用CreateFileMapping()获取映射内存对象的句柄.

我完全按照MSDN网站的说法做到:http://msdn.microsoft.com/en-us/library/aa366551( v = VS.85).aspx:

hFileMappingHandle = CreateFileMapping
    (
        INVALID_HANDLE_VALUE,      // use paging file
        NULL,                      // default security 
        PAGE_READWRITE,            // read/write access
        0,            // maximum object size (high-order DWORD) 
        256,            // maximum object size (low-order DWORD)  
        "Global\\MyFileMappingObject"          // name of mapping object
    ); 
DWORD dwError = GetLastError();
Run Code Online (Sandbox Code Playgroud)

但是,返回的句柄始终为0x0,并且返回的系统错误代码为:0x5(拒绝访问.)

  • 仅需要命名的内存共享(不是文件共享).
  • Windows 7 x64位操作系统
  • 管理员的用户权限可用
  • 开发应用程序:64位插件应用程序(.dll)

有没有人有同样的经历,还有一种解决方法吗?我使用MSDN网站作为我的参考,所以我不认为,代码中存在问题.

c++ windows winapi memory-mapped-files windows-7

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

使用内存映射文件所消耗的时间难以理解

我正在编写一个例程来使用内存映射文件比较两个文件.如果文件太大而无法一次映射.我拆分文件并逐个映射它们.例如,要映射1049MB文件,我将其分为512MB + 512MB + 25MB.

除了一件事之外,每件事情都运行良好:比较剩余部分(本例中为25MB)总是花费更多,更长的时间,尽管代码逻辑完全相同.3观察:

  1. 首先进行比较无关紧要,无论主要部分(512MB*N)还是剩余部分(本例中为25MB)都是第一位,结果保持不变
  2. 其余的额外时间似乎花在用户模式上
  3. VS2010 beta 1中的分析显示,时间花费在t内std::_Equal(),但这个函数主要是(分析器说100%)等待I/O和其他线程.

我试过了

  • 将VIEW_SIZE_FACTOR更改为另一个值
  • 用成员函数替换lambda仿函数
  • 更改测试中的文件大小
  • 将余数的执行顺序更改为循环之前/之后

结果非常一致:在剩余部分和用户模式中需要花费更多时间.

我怀疑它与映射大小不是映射对齐的倍数(在我的系统上为64K)这一事实有关,但不确定如何.

下面是例程的完整代码和3G文件的时序.

谁能解释一下,谢谢?

// using memory-mapped file
template <size_t VIEW_SIZE_FACTOR>
struct is_equal_by_mmapT
{
public:
    bool operator()(const path_type& p1, const path_type& p2)
    {
        using boost::filesystem::exists;
        using boost::filesystem::file_size;

        try
        {
            if(!(exists(p1) && exists(p2))) return false;

            const size_t segment_size = mapped_file_source::alignment() * VIEW_SIZE_FACTOR;  

            // lanmbda 
            boost::function<bool(size_t, size_t)> segment_compare = 
            [&](size_t seg_size, size_t offset)->bool 
            {
                using boost::iostreams::mapped_file_source;
                boost::chrono::run_timer t;     

                mapped_file_source mf1, mf2; …
Run Code Online (Sandbox Code Playgroud)

c++ boost memory-mapped-files

10
推荐指数
1
解决办法
1536
查看次数

为什么MappedByteBuffer的array()方法不起作用?

我是Java的新手,并尝试使用Mathematica的Java接口来使用内存映射来访问文件(希望提高性能).

我所拥有的Mathematica代码(我相信)相当于以下Java代码(基于):

import java.io.FileInputStream;
import java.nio.MappedByteBuffer;
import java.nio.channels.FileChannel;

public class MainClass {
  private static final int LENGTH = 8*100;

  public static void main(String[] args) throws Exception {
    MappedByteBuffer buffer = new FileInputStream("test.bin").getChannel().map(FileChannel.MapMode.READ_ONLY, 0, LENGTH);
    buffer.load();
    buffer.isLoaded(); // returns false, why?
  }
}
Run Code Online (Sandbox Code Playgroud)

我想array()在缓冲区上使用该方法,所以我首先尝试将缓冲区内容加载到内存中load().但是,即使之后load(),isLoaded()返回falsebuffer.array()抛出异常:java.lang.UnsupportedOperationException at java.nio.ByteBuffer.array(ByteBuffer.java:940).

为什么不加载缓冲区以及如何调用该array()方法?

我的最终目标是获得一系列double的使用asDoubleBuffer().array().该方法getDouble()确实可以正常工作,但我希望能够一次完成这项工作以获得良好的性能.我究竟做错了什么?


正如我在Mathematica中所做的那样,我将发布我使用的实际Mathematica代码(相当于Java中的上述代码):

Needs["JLink`"]
LoadJavaClass["java.nio.channels.FileChannel$MapMode"]
buffer = JavaNew["java.io.FileInputStream", "test.bin"]@getChannel[]@map[FileChannel$MapMode`READUONLY, 0, 8*100] …
Run Code Online (Sandbox Code Playgroud)

java wolfram-mathematica memory-mapped-files jlink

10
推荐指数
1
解决办法
5574
查看次数

如何异步刷新内存映射文件?

我使用内存映射文件对Windows 7 64位下的大量图像文件(~10000 x 16 MB)进行读/写访问.我的目标是:

  1. 尽可能多地缓存数据.

  2. 能够分配新图像并尽快写入.

因此我使用内存映射文件来访问文件.缓存效果很好,但操作系统不会刷新脏页,直到我几乎没有物理内存.因为一旦物理内存被填满,分配和写入新文件就会很慢.

一种解决方案是定期使用FlushViewOfFiles(),但在数据写入磁盘之前,此函数不会返回.

有没有办法异步刷新文件映射?我发现的唯一的解决办法是Unmap()MapViewOfFile()再次,但使用这种方法,我不能肯定再次获得相同的数据指针.有人可以提出更好的方法吗?

编辑:阅读WINAPI文档一段时间,似乎我找到了适合我的问题的解决方案:

调用VirtualUnlock()未锁定的内存范围会导致刷新脏页.

c++ memory-mapped-files

10
推荐指数
1
解决办法
2020
查看次数

将内存映射与服务一起使用

我构建了一个应用程序,它也可以作为服务(使用-service)开关运行。当我从命令提示符运行服务时,这完全没有问题(我有一些设置可以让我在不作为真正的服务运行时从控制台调试它)。但是,当我尝试将它作为真正的服务运行,然后使用我的应用程序打开现有的内存映射时,出现错误...

找不到指定的文件。

我如何将它作为服务或在控制台中运行:

[STAThread]
static void Main(string[] args)
{
    //Convert all arguments to lower
    args = Array.ConvertAll(args, e => e.ToLower());

    //Create the container object for the settings to be stored
    Settings.Bag = new SettingsBag();

    //Check if we want to run this as a service
    bool runAsService = args.Contains("-service");

    //Check if debugging
    bool debug = Environment.UserInteractive;

    //Catch all unhandled exceptions as well
    if (!debug || debug)
    {
        Application.SetUnhandledExceptionMode(UnhandledExceptionMode.CatchException);
        AppDomain.CurrentDomain.UnhandledException += CurrentDomain_UnhandledException;
    }

    if (runAsService)
    {
        //Create service array
        ServiceBase[] …
Run Code Online (Sandbox Code Playgroud)

c# shared-memory memory-mapped-files memory-mapping

10
推荐指数
1
解决办法
555
查看次数

内存映射文件std :: allocator实现冻结WM6设备

我有一个适用于Windows Mobile 6.x的Visual Studio 2008 C++项目,我需要的内存比32MB进程插槽中的内存要多.所以,我正在寻找使用内存映射文件.我创建了一个标准的allocator实现,用CreateFileMappingMapViewOfFile替换new/delete .

预期用途是这样的:

struct Foo
{
    char a[ 1024 ];
};

int _tmain( int argc, _TCHAR* argv[] )
{
    std::vector< boost::shared_ptr< Foo > > v;
    for( int i = 0; i < 40000; ++i )
    {
        v.push_back( boost::allocate_shared< Foo >( MappedFileAllocator< Foo >() ) );
    }
    return 0;
}
Run Code Online (Sandbox Code Playgroud)

有了std::allocator,我可以在例如28197次迭代之前,我得到一个std::bad_alloc例外.有了MappedFileAllocator,我在设备完全冻结之前得到了32371次迭代,并且必须重新启动.由于我的设备有512MB的RAM,我希望能够从该循环中获得更多的迭代.

我的MappedFileAllocator实施是:

template< class T >
class MappedFileAllocator
{
public:
    typedef T         value_type;
    typedef …
Run Code Online (Sandbox Code Playgroud)

c++ memory windows-mobile virtual-memory memory-mapped-files

9
推荐指数
1
解决办法
1609
查看次数

附加调试器的C#代码非常慢; MemoryMappedFile的错?

我有一个客户端/服务器应用程序.服务器组件运行,以"远程处理"方式使用WCF(二进制格式化程序,会话对象).

如果我启动服务器组件并启动客户端,则服务器执行的第一项任务将在<0.5秒内完成.

如果我在连接了VS调试器的情况下启动服务器组件,然后启动客户端,则任务需要20秒才能完成.

没有代码更改 - 没有条件编译更改.无论我是否已经编译并运行32位,64位服务器组件,VS主机进程,没有VS主机进程,或者这些东西的任何组合,都会出现同样的情况.

可能很重要:如果我使用VS.NET 探查器(采样模式),那么应用程序运行速度就像没有连接调试器一样.所以我不能那样诊断它.刚检查,仪表模式也快速运行.对于并发性分析模式,同样快速.

关键数据:

  • 该应用程序使用相当繁重的多线程(标准线程池中的40个线程).无论如何,创建线程都会很快发生,而且不是一个慢点.有许多锁,WaitHandles和Monitor模式
  • 该应用程序完全没有例外.
  • 该应用程序不会创建控制台输出
  • 该应用程序完全是托管代码.
  • 该应用程序确实将磁盘上的几个文件映射到MemoryMappedFile:1x750MB和12x8MB以及一些较小的文件

测量性能:

  • 两种情况下CPU使用率都很低; 连接调试器时,CPU位于<1%
  • 两种情况下内存使用都很少; 两种情况下可能都是50或60MB
  • 发生了大量的页面错误(参考MMF),但是在附加调试器时它们发生得更慢
  • 如果VS宿主进程不使用,或基本上是"远程调试监视器"进场,则使用一个体面的CPU,并创建一个良好的数量页面错误的.但这不是问题发生的唯一时间
  • 无论客户端如何运行,都会看到性能差异.唯一要更改的变量是通过"从调试开始"vs从Explorer启动的服务器组件.

我的想法:

  • 调试时WCF速度慢?
  • MemoryMappedFiles在调试时会变慢吗?
  • 使用了40个线程 - 调试速度慢?也许Monitors/locks通知调试器?线程调度变得奇怪/上下文切换非常罕见?
  • 宇宙背景辐射赋予VS智慧和残酷的幽默感

所有人似乎都不太可能.

所以,我的问题:

  1. 为什么会这样?
  2. 如果#1未知,我该如何诊断/发现?

c# debugging performance .net-4.0 memory-mapped-files

9
推荐指数
2
解决办法
4315
查看次数

内存映射文件的性能特征

背景:

我有一个Java应用程序,它在相当大的内存映射文件(> 500 MB)上执行密集IO.程序读取数据,写入数据,有时同时执行两者.

所有读/写功能都具有类似的计算复杂性.

我对程序的IO层进行了基准测试,并注意到内存映射文件的奇怪性能特征:

  • 它每秒执行90k次读取(每次迭代在随机位置读取1KB)
  • 它每秒执行38k次写入(每次迭代写入1KB)
  • 它每秒执行43k次写入(每次迭代在随机位置写入4个字节)
  • 它每秒仅执行9k读/写组合操作(读取12个字节,然后每次迭代写入1KB,随机位置)

64位JDK 1.7,Linux 3.4上的程序.

该机器是普通的英特尔PC,具有8个线程CPU和4GB物理内存.在执行基准测试时,仅为JVM堆分配了1 GB.

如果需要更多细节,请参考以下基准代码:https://github.com/HouzuoGuo/Aurinko2/blob/master/src/test/scala/storage/Benchmark.scala

以下是上述读,写,读/写函数的实现:https://github.com/HouzuoGuo/Aurinko2/blob/master/src/main/scala/aurinko2/storage/Collection.scala

所以我的问题是:

  • 给定固定文件大小和内存大小,哪些因素会影响内存映射文件的随机读取性能?
  • 给定固定文件大小和内存大小,哪些因素会影响内存映射文件的随机写入性能?
  • 如何解释读/写组合操作的基准测试结果?(我希望它每秒执行超过20K的迭代次数).

谢谢.

java linux memory-mapped-files

9
推荐指数
1
解决办法
1321
查看次数

Java - 内存映射文件的好处

我很难在Java中看到内存映射文件(缓冲区)的好处.这是我在实践中看到的方法:

我们将文件块映射到主存储器中,直接处理内存中的任何写入/读取,让OS完成将文件保存到磁盘中的工作.

现在,我想将它与常规I/O和一些场景进行对比:

  1. 附加到文件中

为了将文件映射到mem,我必须将其作为一个整体阅读,以进行整体修改.缓冲区大小最初是文件的大小(假设我不知道我要写入文件的数据量).现在,为了附加到文件,我不能这样做,因为缓冲区的大小有限.所以最基本的操作对我来说似乎不可能.另外,读取整个文件以附加一小部分似乎相当浪费.所以我认为常规I/O在这种情况下表现更好.

  1. 坚持改变

为了坚持更改,我仍然需要刷新它们.因此,如果我不定期这样做,我可能会丢失主内存中的更改.这与常规I/O流的想法相同,因此这里也没有增益.

  1. 随机变化

这是我可以看到它工作的地方 - 用其他n个字节替换n个字节.尽管如此,将m个字符替换为m个字符似乎相当不寻常.我们宁愿拥有Hello并替换它Hi.但是我们有一个填充的,固定大小的缓冲区,所以这并不容易......此外,它让我想起RandomAccessFile了更好的性能.

可能我写的大部分内容都是无意义的,但我会很高兴被告知,至于我的内存,MemoryMappedBuffer似乎很难,也很麻烦(甚至不可能)使用.

java nio memory-mapped-files

9
推荐指数
1
解决办法
1435
查看次数

内存映射随着时间的推移而减慢,替代方案?

我有大约700个矩阵存储在磁盘上,每个矩阵有大约70k行和300列.

我必须相对快速地加载这些矩阵的部分,每个矩阵大约1k行,到内存中的另一个矩阵.我发现这样做的最快方法是使用内存映射,最初我能够在0.02秒内加载1k行.但是,性能根本不一致,有时每个矩阵的加载时间长达1秒!

我的代码大致如下:

target = np.zeros((7000, 300))
target.fill(-1)  # allocate memory

for path in os.listdir(folder_with_memmaps):
    X = np.memmap(path, dtype=_DTYPE_MEMMAPS, mode='r', shape=(70000, 300))
    indices_in_target = ... # some magic
    indices_in_X = ... # some magic
    target[indices_in_target, :] = X[indices_in_X, :]
Run Code Online (Sandbox Code Playgroud)

随着时间的推移,我确定它绝对是随着时间的推移而减速的最后一条线.


Upadte:绘制加载时间会产生不同的结果.有一次它看起来像这样,即降级不是渐进的,而是在恰好400个文件之后跳跃.这可能是一些操作系统限制吗?

Plot1

但另一次看起来完全不同:

Plot2

经过几次测试后,第二个图似乎是性能开发的典型.


另外,我试着del X在循环之后,没有任何影响.也没有mmap通过X._mmap.close()工作访问底层Python .


有关为什么表现不一致的任何想法?有没有更快的替代品来存储和检索这些矩阵?

python unix performance numpy memory-mapped-files

9
推荐指数
1
解决办法
546
查看次数