所以,我找到了这个SynScaleMM.任何人都可以给它一些反馈或在类似的内存管理器?
谢谢
解决方法
编辑:看看更稳定的ScaleMM2和全新的SAPMM.但是我下面的说法还是值得的:你做的分配越少越好你的规模!
但是它在多线程服务器环境中的工作正常.对于一些关键测试,缩放比FastMM4好得多.
但内存管理器可能不是多线程应用程序中更大的瓶颈. FastMM4可以很好的工作,如果你不强调它.
这里有一些(不是教条,只是从实验和知识的低级Delphi RTL)建议如果你想在Delphi中写FAST多线程应用程序:
>始终使用const作为字符串或动态数组参数,如MyFunc(const aString:String),以避免每次调用分配一个临时字符串;
>避免使用字符串连接(s:= s’Blabla’IntToStr(i)),但依赖于最新版本的Delphi中提供的缓冲写入,如TStringBuilder;
> TStringBuilder也不完美:例如,它将创建大量的临时字符串来附加一些数字数据,并且当您添加一些整数值时,将使用非常慢的SysUtils.IntToStr()函数 – 我必须重写很多低级功能,以避免在我们的TTextWriter类中大多数字符串分配,如SynCommons.pas所定义;
>不要滥用关键部分,让它们尽可能的小,但如果需要一些并发访问,则依赖某些原子修饰符. InterlockedIncrement / InterlockedExchangeAdd;
> InterlockedExchange(来自SysUtils.pas)是更新缓冲区或共享对象的好方法.您在线程中创建一些内容的更新版本,然后在一个低级cpu操作中交换共享指针到数据(例如TObject实例).它会通过非常好的多线程缩放通知其他线程的更改.你必须要照顾数据的完整性,但在实践中效果很好.
>不要在线程之间共享数据,而是使自己的私有副本或依赖一些只读缓冲区(RCU模式更适合缩放);
>不要使用索引访问字符串字符,而是依赖于一些优化的函数,如PosEx();
>不要混合AnsiString / UnicodeString类型的变量/函数,并通过Alt-F2检查生成的asm代码来跟踪任何隐藏的不必要的转换(例如调用UStrFromPCharLen);
>而不是在一个过程中使用var参数,而不是返回一个字符串的函数(返回一个字符串的函数将添加一个具有LOCK的UStrAsg / LStrAsg调用,它将刷新所有cpu内核);
>如果可以,对于数据或文本解析,使用指针和一些静态堆栈分配的缓冲区,而不是临时字符串或动态数组;
>每次需要一个时,不要创建一个TMemoryStream,而是依赖于你的类中的一个私有的实例,它已经有足够的内存大小,你可以使用Position来写入数据来检索数据的结尾,而不是改变它的大小将由MM分配的内存块);
>限制您创建的类实例的数量:尝试重用同一个实例,如果可以,在已分配的内存缓冲区上使用一些记录/对象指针,将数据映射到不复制到临时内存中;
>始终使用测试驱动的开发,采用专门的多线程测试,试图达到最差的限制(增加线程数,数据内容,添加一些不一致的数据,随机暂停,尝试压缩网络或磁盘访问,基准实时数据的时间…);
>永远不要相信你的本能,而是在真实的数据和流程上使用准确的时间.