我有一些java代码正在执行以下操作:
Statement stmt = GetMsSqlConnection().createStatement(ResultSet.TYPE_FORWARD_ONLY,
ResultSet.CONCUR_READ_ONLY);
ResultSet rs = stmt.executeQuery("SELECT * FROM Table WHERE ID=1");
//do stuff with recordset
rs.close();
stmt.close();
这是循环的一部分,我在桌面上浏览不同的ID。问题是,虽然这是循环,但我看到我的SQL Server进程的RAM在每次迭代中都在增长。当我单步执行代码时,我注意到导致问题的行是在executeQuery调用上。我并不感到惊讶,这会导致RAM的使用增加,但我认为rs.close和stmt.close会释放我的SQL Server上的资源。在我的环境中是否有更好的处理这个或类似的东西我需要注意以确保我在下一次迭代之前释放所有资源?
答案 0 :(得分:2)
我在阅读结果集时遇到了内存不足的问题。许多当前论坛重新指向使用游标和获取大小。但是,当我添加Cursor和fetch size选项时,OOM问题未得到解决。相反,我们观察到当多个线程尝试读取结果集并发送数据时存在死锁。 另外,我没有注意到更改获取大小和添加游标时内存消耗的任何变化: 获取大小光标MemoryConsumed(MB) 1折209 关闭151 关闭132 OFF OFF 160
在努力解决这些问题时,我碰巧登陆了一个博客,为解析只读结果集提供了更好的选择 - ResponseBuffering = Adaptive option
http://technet.microsoft.com/en-us/library/bb879937(v=sql.110).aspx
MSDN建议建议不要使用' selectMethod' =' cursor'只读大型数据集和更好的选择是使用' responseBuffering' =' adaptive'
使用' responseBuffering' ='自适应'我们能够摆脱这两个问题: 1.内存不足问题已得到解决 2.没有死锁。 使用最简单的代码,有5个源的2000000条记录的数据传输失败。添加自适应响应缓冲功能可以为每个源传输2000000条记录,其中包含40个源,没有任何问题。但是,这并不意味着超过40个来源转移失败。
对于大型只读结果集,将响应缓冲设置为自适应是最佳选择。
这是我详细博客的链接: http://pallavikaranjkar.blogspot.in/2014/10/context-existing-system-sends-data-from.html
答案 1 :(得分:1)
服务器只是缓存最近访问过的页面。如果允许,MSSQL将使用系统中可用的所有内存。这不是内存泄漏,MSSQL不会耗尽内存,它只会从缓存中开始逐出最少使用的页面。
答案 2 :(得分:0)
服务器可能会推迟清理,直到达到某个阈值。垃圾收集很昂贵,因此每次释放资源时都不会这样做。如果连续运行数千个这样的服务器,服务器内存使用情况的图表可能会显示一个锯齿模式,其中内存线性增加,然后在GC发生时丢失,重复一遍又一遍。
所有数据库服务器都有参数来调整内存使用情况,并调整它们运行的硬件。