我希望使用命名共享内存来实现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();
但是,返回的句柄始终为0x0,并且返回的系统错误代码为:0x5(拒绝访问.)
有没有人有同样的经历,还有一种解决方法吗?我使用MSDN网站作为我的参考,所以我不认为,代码中存在问题.
我正在编写一个例程来使用内存映射文件比较两个文件.如果文件太大而无法一次映射.我拆分文件并逐个映射它们.例如,要映射1049MB文件,我将其分为512MB + 512MB + 25MB.
除了一件事之外,每件事情都运行良好:比较剩余部分(本例中为25MB)总是花费更多,更长的时间,尽管代码逻辑完全相同.3观察:
std::_Equal(),但这个函数主要是(分析器说100%)等待I/O和其他线程.我试过了
结果非常一致:在剩余部分和用户模式中需要花费更多时间.
我怀疑它与映射大小不是映射对齐的倍数(在我的系统上为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; …我是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?
  }
}
我想array()在缓冲区上使用该方法,所以我首先尝试将缓冲区内容加载到内存中load().但是,即使之后load(),isLoaded()返回false并buffer.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] …我使用内存映射文件对Windows 7 64位下的大量图像文件(~10000 x 16 MB)进行读/写访问.我的目标是:
尽可能多地缓存数据.
能够分配新图像并尽快写入.
因此我使用内存映射文件来访问文件.缓存效果很好,但操作系统不会刷新脏页,直到我几乎没有物理内存.因为一旦物理内存被填满,分配和写入新文件就会很慢.
一种解决方案是定期使用FlushViewOfFiles(),但在数据写入磁盘之前,此函数不会返回.
有没有办法异步刷新文件映射?我发现的唯一的解决办法是Unmap()和MapViewOfFile()再次,但使用这种方法,我不能肯定再次获得相同的数据指针.有人可以提出更好的方法吗?
编辑:阅读WINAPI文档一段时间,似乎我找到了适合我的问题的解决方案:
调用VirtualUnlock()未锁定的内存范围会导致刷新脏页.
我构建了一个应用程序,它也可以作为服务(使用-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[] …我有一个适用于Windows Mobile 6.x的Visual Studio 2008 C++项目,我需要的内存比32MB进程插槽中的内存要多.所以,我正在寻找使用内存映射文件.我创建了一个标准的allocator实现,用CreateFileMapping和MapViewOfFile替换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;
}
有了std::allocator,我可以在例如28197次迭代之前,我得到一个std::bad_alloc例外.有了MappedFileAllocator,我在设备完全冻结之前得到了32371次迭代,并且必须重新启动.由于我的设备有512MB的RAM,我希望能够从该循环中获得更多的迭代.
我的MappedFileAllocator实施是:
template< class T >
class MappedFileAllocator
{
public:
    typedef T         value_type;
    typedef …c++ memory windows-mobile virtual-memory memory-mapped-files
我有一个客户端/服务器应用程序.服务器组件运行,以"远程处理"方式使用WCF(二进制格式化程序,会话对象).
如果我启动服务器组件并启动客户端,则服务器执行的第一项任务将在<0.5秒内完成.
如果我在连接了VS调试器的情况下启动服务器组件,然后启动客户端,则任务需要20秒才能完成.
没有代码更改 - 没有条件编译更改.无论我是否已经编译并运行32位,64位服务器组件,VS主机进程,没有VS主机进程,或者这些东西的任何组合,都会出现同样的情况.
可能很重要:如果我使用VS.NET 探查器(采样模式),那么应用程序运行速度就像没有连接调试器一样.所以我不能那样诊断它.刚检查,仪表模式也快速运行.对于并发性分析模式,同样快速.
关键数据:
WaitHandles和Monitor模式测量性能:
我的想法:
所有人似乎都不太可能.
所以,我的问题:
背景:
我有一个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
所以我的问题是:
谢谢.
我很难在Java中看到内存映射文件(缓冲区)的好处.这是我在实践中看到的方法:
我们将文件块映射到主存储器中,直接处理内存中的任何写入/读取,让OS完成将文件保存到磁盘中的工作.
现在,我想将它与常规I/O和一些场景进行对比:
为了将文件映射到mem,我必须将其作为一个整体阅读,以进行整体修改.缓冲区大小最初是文件的大小(假设我不知道我要写入文件的数据量).现在,为了附加到文件,我不能这样做,因为缓冲区的大小有限.所以最基本的操作对我来说似乎不可能.另外,读取整个文件以附加一小部分似乎相当浪费.所以我认为常规I/O在这种情况下表现更好.
为了坚持更改,我仍然需要刷新它们.因此,如果我不定期这样做,我可能会丢失主内存中的更改.这与常规I/O流的想法相同,因此这里也没有增益.
这是我可以看到它工作的地方 - 用其他n个字节替换n个字节.尽管如此,将m个字符替换为m个字符似乎相当不寻常.我们宁愿拥有Hello并替换它Hi.但是我们有一个填充的,固定大小的缓冲区,所以这并不容易......此外,它让我想起RandomAccessFile了更好的性能.
可能我写的大部分内容都是无意义的,但我会很高兴被告知,至于我的内存,MemoryMappedBuffer似乎很难,也很麻烦(甚至不可能)使用.
我有大约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, :]
随着时间的推移,我确定它绝对是随着时间的推移而减速的最后一条线.
Upadte:绘制加载时间会产生不同的结果.有一次它看起来像这样,即降级不是渐进的,而是在恰好400个文件之后跳跃.这可能是一些操作系统限制吗?
但另一次看起来完全不同:
经过几次测试后,第二个图似乎是性能开发的典型.
另外,我试着del X在循环之后,没有任何影响.也没有mmap通过X._mmap.close()工作访问底层Python .
有关为什么表现不一致的任何想法?有没有更快的替代品来存储和检索这些矩阵?