条件:
1、机器配置CPU2.4 ;内存:2G ;硬盘:80G
2、我想利用内存存放大量的文件。
3、我有10w个20k的文件重的开始:
4、我想在我的程序启动的时候加载到一个容器中
   map<CString,char*,less<CString> > MyMap ;
问题:
1、我在加载的过程中发现内存在增长,但是到一定的程度确突然降低很低,我想可以室页面交换了。 
   我要问的第一个问题是:我的内存还有很多的Free空间,为什么会进行页面交换那?
2、我能不能自己 控制页面交换?
3、我的把很大文件放入内存的行为是否有效?(我在程序中非常频繁地要访问每一个文件,所以我才放入内存中的,为了提高效率)
4、有没有可以替代的很优化的方案?(方案合适我愿意奉献1000分)
欢迎大侠们讨论:谢谢
   

解决方案 »

  1.   

    条件:
    1、机器配置CPU2.4 ;内存:2G ;硬盘:80G
    2、我想利用内存存放大量的文件。
    3、我有10w个20k的文件重点开始:
    4、我想在我的程序启动的时候加载到一个容器中
       map<CString,char*,less<CString> > MyMap ;
    问题:
    1、我在加载的过程中发现内存在增长,但是到一定的程度确突然降低很低,我想可以室页面交换了。 
       我要问的第一个问题是:我的内存还有很多的Free空间,为什么会进行页面交换那?
    2、我能不能自己 控制页面交换?
    3、我的把很大文件放入内存的行为是否有效?(我在程序中非常频繁地要访问每一个文件,所以我才放入内存中的,为了提高效率)
    4、有没有可以替代的很优化的方案?(方案合适我愿意奉献1000分)
    欢迎大侠们讨论:谢谢
    能提供代码者兄弟愿意2000分酬谢。
      

  2.   

    1 Windows并不是等内存用尽才进行内存交换。
    2 可以锁定某块内存不进行内存交换
    3 没什么效果,还不如把操作系统的磁盘高速缓存改大一点比较快
    4 同上
      

  3.   

    TO konista(M) 
    我的程序在允许过程中。要非常频繁地访问文件。如果每次访问的时候打开文件。效率显然是很低的。
    我原来是这样处理的,为了提高效率,把大量的下文件放入到内存中,使用时从内存中直接读取,当然要比从磁盘上要快很多。理由是否充分???谢谢。
      

  4.   

    我有10w个20k的文件这里做个初步估计:
    100000个大概需要2G的内存,用2000SEVER以上的,把user space打开到3G,所有其它的
    事情可由OS代劳。
      

  5.   

    同意ipgk(loboho),10w个20k的文件,简直可以算是大型操作了,而且访问频繁,还要随时修改,这种情况用文件显然不合理,而且楼主说得内存情况,像你这么多的小文件,全拿到内存里也不现实,而且os支配大多数内存空间,所以你的文件虽说在动态内存中操作,实际还是映射到了硬盘上,速度也不见得快了多少
    因此本身这种应用的设计就有很大的问题和疑问,像这种需要大量数据操作的情况,完全应该使用数据库来完成,而且还要对数据进行优化才能有明显的效率提升如果不是情况非常特殊,强烈推荐使用数据库来代替小文件
      

  6.   

    TO  welcome_ck(风小云) 
    我们的服务器使用的是Oracle9i,我们讨论的是我们客户端上的数据,我不可能给100个客户端都安上Oracle,成本我们都受不了?不是吗? 所以采用文件的方式是必须的选择。
      

  7.   

    拼成一个大文件,用文件映射操作,在文件头用hash索引文件名及文件偏移,我想效率会比10w个文件要好的多
      

  8.   

    TO roger_ding(海天一色) 
    如果拼成的一个文件有2G,映射到内存中,操作速度然后?和内存中直接读取相比!
      

  9.   

    TO allenhe(一定要过二级) 
    你能说详细一些吗?谢谢
      

  10.   

    把所有文件都放入内存不可能.如果是我的话,我会这样做.
    0.在内存开辟一块区域,大小是i个文件的和,如果你是10w个文件的话可以考虑i==100;
      VirtualAllocaEx(....,i*file_size ,.....);
      随机的把i个文件放入这个内存区域,比如第1,2,3个文件
      CFile::Read(...);
    1.定义一个数组 
      dwProbaility[FILE_NUMBER];
      ZeroMemory( dwProbaility, FILE_NUMBER );2.如果需要某一个文件写入内存,比如第M个内存写入内存则: OnSomeFileWriting2Mem( WPARAM wParam, LPARAM lParam )
    {
         int nFileNumber = (int)wParam;
         dwProbaility[nFileNumber]++;
         return nFileNumber;
    }3. 每隔n秒,更新内存池,
    对 dwProbaility 把出现几率最大的文件copy如内存,几率小的剔除内存
    @@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@
    以上是非常大概的写一下,相信这个方法是兼顾效率与成本.......p.s: 对于第三步其实可以有一个更好的方法~
    设置3个逻辑缓冲区1.   物理内存区    存放出现几率最大的文件
    2.   虚拟内存区    存放几率次大的文件
    3.   硬盘区        存放几率非常小的文件p.s2: 事实上,这是以几率来进行操作优化,对于具体问题可以具体考虑,
          对于10w个文件的优化,很难相信会没有任何文件操作上规律可循,比如操作工资表,很有可能是从男到女,或者从职务高到低,这样的话,优化就应该从这样的方向入手....--The End--
      

  11.   

    如果是你读取文件,是读,windows的映射文件读,也是读,但是windows的映射文件的读取效率比分开读要高!
      

  12.   

    TO  norsd(norsd) 
    首先感谢您的方案,感谢大家的参与。1、我的程序首先要保证一条。准确!是就是。不是就不是,一步到位。绝对不能出现模凌两可的现象。
    2、我的10w个文件都是一些特征信息文件,他们一般很少修改(写入文件),大部分是读取操作。
    3、我们的远程用户发来一个请求,当然同时发来一些数据,我必须把他发来的数据和我们10w个文件中的部分进行对照,把符合要求的文件名称反馈给远程User ,而且user的数据是没有任务规律的。所以我才想到全部放入内存中,在内存中查找文件当然是快了。
      

  13.   

    我初步打算把每1000个20k的小文件拼成一个大文件,这样读取一个20m的文件总比读取1000个20k的文件效率要高很多。拼装的规则:如 roger_ding(海天一色) 说的“在文件头用hash索引文件名及文件偏移”这样我读取的就是100个文件就可以了。如果需要我可以从文件头中解析具体的某一个文件名称和Data;
      

  14.   

    或许可以获取某些文件特征将这些文件特征当作索引存储在数据库中,客户发送过来的请求可以携带这样的索引,然后服务器根据索引在数据库中去查找,数据库中除了索引,也许还可以存文件的具体位置,建立和修改日期,等等其他信息,当在数据库中找到这个索引值后,可以获取文件的物理位置,然后进行访问。
    拼成一个大文件的短处:首先因为文件太大,不便维护,虽然你说不需要经常修改,但是如果需要维护,试想,一个2G或20M的文件你要如何维护;其次,按照你所说,是客户想服务器请求,这样,想一想如何服务器同时受到若干个客户端的请求,单按照文件访问的方法,不能保证访问效率;然后,如果你现在要对这个2G或20M的文件做一些事情,比如换一台服务器存放、添加一些新纪录,有加入其中某个部分出了问题,2G或20M的文件,岂不是所有的东西都不能正常使用了??而且文件的读取速度不敢恭维
    合成一个大文件一定不可行
    因此,找出现在10W个小文件的特征,取得有利的部分,将它们存到数据库进行管理,不但便于维护,而且数据库对查询、多用户的支持绝对比2G或20M的文件要好
      

  15.   

    上面norsd(norsd)朋友的提案绝对有力度,不过做件东西很大程度不应该首先想从最底层做起,这样不但容易因为实现本身的复杂性使得项目最终搁浅,而且绝对会耗费很大的人力和物力,更不会得到领导的认可。
    还有,你完全没有必要在所有人的机器上都装Oracle,只需要做一个客户端的软体,使用socket来向服务器请求,服务器做一个服务端的软体,获取每一个请求到本地的数据库去查询就可以了。
    问题的难度主要集中在首先你需要能找出这些文件的特征,然后建立索引,这是必要的,然后难度集中在如何使得不同的客户端的请求能及时响应,而且不会出现死锁
    希望你认真想想使用文件的可靠性,也希望能帮得上你
      

  16.   

    TO  welcome_ck(风小云) 
    使用数据库我已经考虑过了,只所以没有选择他的原因:
    1、Oracle数据库的成本太高
    2、如果采用数据库的方式,工作站访问数据库的太频繁,(每进行一个用户的请求比照最大进行10w*(50-100) 次的数据库访问量,所以不可行,我们采取大量数据分散存放的方式,把特性信息以文件的形式分散到各个工作站上。比照时访问本地的10w文件中的部分。
      

  17.   

    在客户端安装一个免费的数据库不是很好吗,比如MySQL,还有相当于免费的Access。
      

  18.   

    TO welcome_ck(风小云) 1、我的服务器上存放100w的数据:
    2、我有10个工作站,每一个工作站上存放10w个(保证不会重复)
    3、当客户请求对照时,每个工作站负责比照本地的信息,分别反馈给服务器,形成总的比照信息。
    4、在工作站上的比照可能访问每一个文件,如果采取本地缓存的方式,缓存的大小多少合适?
       以文件的形式缓存还是放入内存中?另外大部分数据向服务器请求吗?假设你在本地缓存了5w数据
       ,我的比照基本要求比照每一个文件,也就是说,一个客户请求,我要向服务器另外请求5W 
       次!!!???我想不太可行。如果你打算全部存放到本地,这有和我以前的方案一样,还是读取 
       小文件的效率问题。
      

  19.   

    你没有听懂我的意思!!
    3、当客户请求对照时,每个工作站负责比照本地的信息,分别反馈给服务器,形成总的比照信息。
    4、在工作站上的比照可能访问每一个文件,如果采取本地缓存的方式,缓存的大小多少合适?
    -------------------------------
    建立数据库前做这样的工作:
    找出100w个文件的可表示信息(你说过不会重复):这么说吧,就是有没有这种信息,比如我需要服务器给我需要的数据10,这个10一定存在10.28日的文件里(假设一天生成一个文件,且不重复),那么客户可以变相的发送10.28到服务器,然后服务器的数据库存储的信息就是1.1-10.28类似这样的信息,得到客户端的信息后到数据库中去寻找10.28,然后可以得到该文件存储的地方,然后取出10给用户。那么客户端的缓冲就是把这个10.28和10的结果存在本地,下次只需到缓冲去找有没有10.28就可以了,如果没有再向服务器请求。
    当然在100w个文件中找一个类似10.28的信息当然不是很简单,但你说过100w个文件都不重复,那么就可以从它们不重复内容里提出这样的信息,当然不会像例子中10.28这个日期这么简单。
    ------------------------------------------
                                              索引(10.28)   值(10)(直接存结果)         客户端----->本地缓冲        索引(10.29)   值(11)           |                A                       。
               | 本地缓冲       |新值加入到
               | 没有记录       |缓冲(可以按一定方式替换)
               | 请求服务器     |
               V                |
             服务器----->数据库          索引(10.31)   文件位置(\..)
                                |             索引(10.20)   文件位置(\..)
                                |                       。
                                |找到了文件位置
                                |
                                V
                             访问文件,回应用户请求
    -------------------------------------------
    关键部分就是是否能找到这种唯一的索引,所以必须你从每个文件的不同处提出自己需要的信息再说你有没有想过,你的大文件不是简单的将几个小文件合成,还必须提供一种查找方式,如果这个算法不行,会严重影响效率。还有访问同一个文件5W次和访问不同文件5W次的效率会差多少呢?当然你可以说你能把它放到内存里,但是既然你能保证这个大文件在内存中会用一定的时间不会替换,那么和在客户端开一个缓冲有什么区别,而且没有文件读取时间(数据库更擅长做这个),没有网络消息传输时间(你不会指望把这个大文件传到客户内存中吧)。
    不知你看懂没
      

  20.   

    TO  welcome_ck(风小云)
    我想我没有交代清楚。
    我的msn : [email protected]
    我们明天具体聊聊好吗?
      

  21.   

    业务流程:远程用户请求比照-->>服务器解析比照信息
      A                         |
      |                         |
      |                         V
      |             服务器把比照信息发给处理机(10个)
      |                         |
      |                         |
      |                         V
      |  每一个处理机处理本地分配的文件和比照信息进行比照
      |                         |
      |                         |
      |                         V
      |      各个处理机把各自的比照结果反馈给服务器
      |                         |
      |                         |
      |                         V
      |         服务器合并比照结果,反馈给远程请求
      |                         |
      —————————————|
                               
    比照流程:
                           处理机收到任务
                                 |
                                 V
                    根据比照信息缩小查找文件的范围 
                                 |
                |--------------> V 
                |       形成要读取的文件的列表
                |                 |
                |                 V
                |       读取每一个文件并进行比照
                |                 |
                |                 |
                |                 V
                |            形成比照结果
                |                 |
                ----------------<-|循环处理所有的文件现在是关键改造第二个流程。
    本地的文件信息和该文件的位置信息已经被提炼出来,存放在一个索引文件中了,每来一个任务
    都形成一个候选的文件列表,我根据候选的文件列表进行比照。
      

  22.   

    TO welcome_ck(风小云)
    TO 疑问1:
     我得到的结果可能不是一个
     to 疑问2:
      查找时确实形成一个范围,可能范围很大,也可能只有几千,几百。
    TO  Others我的其他部分不会影响到比照的效率。
    所以现在我主要改造比照部分。他是进行对比的核心。
      

  23.   

    呵呵,jiangsheng(蒋晟.MSMVP2004Jan)吗
    Microsoft Most Valuable Person 2004 January!!MVP哦,高手,自我简介一下吧
      

  24.   

    TO jiangsheng(蒋晟.MSMVP2004Jan)
    大侠的为什么不出手那?不要吝啬吗。
      

  25.   

    那你的问题也就是要改进这个比照的效率了,呵呵
    先看看以前的比照做了什么
    首先,用户发送请求,服务器接收,一切正常,但到了索引文件,read file,查找,我想你一定是通过一个索引指针的方法实现是吧,呵呵,好每次指针累加到下个地址,然后做什么?虽然和第一次read file有区别,但不可否认,地址中的东西一定在硬盘上,不管内存怎么分配,只要现在内存没有信息,一定需要读硬盘来获取,可能下次请求需要的信息在硬盘里,但就这一次请求来说,需要不断的读硬盘写到内存,请求完成后呢,呵呵,希望你不要把有关这个file的内存空间释放了,不然下次请求来又要...这是在索引文件里做的;然后结果有几千、几百个,每个又是不同的文件,然后又read file,呵呵,这个read file工作可谓巨大呀。当然还没有考虑网络的延时:)还有你十多个不同的处理机
    ------------------------
    我开始理解你为什么要改进为大文件了
    我的建议
    1.首先把这个索引文件改进成数据库形式,这个可以实现吧
    2.按你说的,把一部分文件合并,当然有规则,这个规则不但要便于前面数据库中的缩小结果工作,还要便于最后的结果最好在一个文件中
    3.我坚持客户端有一定的缓冲,缓冲中存的是用户的请求信息和最终的结果,也就是不是得到的缩小范围结果而是最终信息,因为你能保证精度,每一次查找同一个信息,得到的结果一样。
    ------------------------
    当然你还要好好想想最好改进一下这个缩小结果的工作效率,也就是改进比照的方法,呵呵,这个可是很见效果的