2013-07-19 23 views
1

我有一个作为服务运行的TCP/IP DataSnap服务器[基于会话的LifeCycle],它不断咀嚼内存,即使没有连接时也不会回到起始内存大小。连接关闭后如何释放DataSnap内存?

为了消除我的代码作为罪魁祸首,我建立了一个基本的TCP/IP DataSnap服务器,作为VCL [基于会话的LifeCycle]运行,服务于Server Method类[TDSServerModule],其中仅包含使用native数据类型[没有要创建或免费的对象]。

当我用一个非常瘦的客户端连接到所述DataSnap服务器时,我得到了相同的结果。 随着每个连接的内存使用量不断增加,并且在从客户端执行服务器端方法时零星增长。一旦连接关闭,DataSnap服务器永远不会减少其内存使用量[即使在没有连接的情况下运行8小时]。

有关为什么发生这种情况或者更重要的是如何减少它的任何建议?

我使用RAD Studio的XE2更新4的HotFix 1

+0

Datasnap已死亡。万岁datasnap! – whosrdaddy

回答

1

让我举一个有关的DataSnap “必读” 的文章。这是关于XE3的,但我希望这里的代码也适用于XE2。

内存消耗

其中一个,我观察到的是有关内存消耗问题。为什么Datasnap服务器消耗如此多的内存,如果被调用的方法完全没有用处?

也许我不知道如何解释,但我会尝试。基本上DataSnap会为它接收的每个HTTP连接创建一个会话。这个环节在20分钟后将被销毁,换句话说,在测试的前20分钟,内存消耗量只会上升,之后会有稳定的趋势。我真的不知道为什么Datasnap会这样做。在REST应用程序中,我在这些会话中看不到很多默认配置。当然,会话可能会有帮助,但我不明白为什么它是默认配置。事实上,DataSnap没有这方面的配置。看起来好像你只需要使用这个会话控制,而不能另外选择(没有文档)。 MORMot框架也有会话控制,但它是可配置的,不会消耗太多内存。

无论如何,有一个解决这个问题的方法。 Daniele Teti在他的博客上写了一篇文章,看一看。我将在这里展示的解决方案由他放在他的博客上。谢谢丹妮尔。

uses System.StrUtils, DataSnap.DSSession, Data.DBXPlatform; 

function TServerMethods1.HelloWorld: String; 
begin 

Result := 'Hello World'; 
GetInvocationMetaData.CloseSession := True; 
end; 

运行此方法后,会话将关闭和内存占用会更低。当然,仍然存在创建和销毁此会话的开销。

因此,对于您来说,最好的方法是结束每个带有显式内存清理的服务器方法,如果这在XE2中是可能的。那么你最好再次阅读这些文章,并为未来的可扩展性挑战做好准备。

+0

感谢您的链接。我已经实现了'GetInvocationMetaData.CloseSession:= True'调用我所有的服务器方法,并且每个方法调用的内存消耗似乎有所减少。 然而,DataSnap服务器似乎仍然消耗每个连接的内存,并且从不释放它。 –

+2

那么也许你最好放弃datasnap –

1

你应该检查你的servercontainer上TDSServerclass组件生命周期属性。它提供了一种确定会话处理方式的方法。它默认为会话。将其设置为invokation可在每次调用(调用)后释放会话。这当然意味着你没有任何国家。尽管这在典型的REST服务器中会出现。

如果你仍然有内存消耗增长。把下面的行放在你的dpr单元中。 ReportMemoryLeaksOnShutdown:= True;
然后,您的应用程序将向您显示它在关闭datasnap服务器时发生的内存泄漏。

+2

正如问题中所述,我已将生命周期设置为Session。我必须使用会话,因为调用征税数据库服务器[Oracle 11g]。 我已经尝试了ReportMemoryLeaksOnShutdown函数,并且DataSnap没有报告任何内容。当服务器关闭并报告泄漏时,我故意将对象保留在内存中。 所以我不认为这是我的代码导致内存增长,我认为它纯粹是DataSnap。 –

+1

很好的答案,像一个真正的老板说... –