SQL Server内部/默认资源池随时间增加

问题描述

问题

我在安装了单个数据库的客户VM上部署了sql Server 2017数据库。该数据库具有一个Web应用程序,该应用程序在高峰时间与大约100个活动用户连接。在过去的几个月中,客户不得不在使用5天后重新启动sql server实例,因为该应用程序开始显示性能下降的迹象(有时加载页面需要一秒钟,然后同一页面可能需要15秒)。我已经监视查询存储已有几个月了,并且对查询进行了性能优化,但是仍然无法防止数据库在本周末出现性能问题。

存在问题时(正常运行时间5天后),尽管一周中查询的频率和运行的查询类型完全相同,但服务器显示出较高的cpu和内存使用率。在遇到问题时查看查询存储后,我看不到任何长时间运行的查询,并且在cpu或内存分析图表上没有什么比应用程序运行良好的日子更高。

我注意到的一件事是,内部/认资源池在整个星期中的使用率都在增加。 重新启动后不久,资源池的使用率就会降低:

enter image description here

5天后,资源池看起来要高得多:

enter image description here

我注意到,当我运行查询时,在运行查询时资源池会增加,但是在查询运行完成后总是会释放内存,这似乎在客户实例上无法正常发生,否则我无法理解为什么资源池会随着时间增加

问题

资源池使用率是否随着时间的增长而增加,可能会导致性能问题?

什么会导致资源池内存不被释放?

为减轻我们所面临的性能问题而实施的措施如下:

  1. 启用READ_COMMITTED_SNAPSHOT隔离,这有助于缓解由于锁定而导致应用程序似乎无响应的问题。
  2. 设置最大服务器内存以确保它不会耗尽操作系统。
  3. 花了几个月的时间来优化一堆查询,以减少cpu持续时间和逻辑读取,并添加了索引,虽然虽然有一定帮助,但并不能解决我的所有问题。

解决方法

我相信我已经找到了这个问题的罪魁祸首。用于连接数据库和执行查询的sqljdbc4.2.jar发生内存泄漏。在运行应用程序的负载测试并监视sys.dm_os_memory_clerks之后,我看到随着对数据库执行越来越多的查询,MEMORYCLERK_SQLCONNECTIONPOOL pages_kb有所增加。这也增加了资源池中的“已用内存”。

将jdbc库更新为更高版本后,MEMORYCLERK_SQLCONNECTIONPOOL不会随着时间的推移而增加。

<dependency>
    <groupId>com.microsoft.sqlserver</groupId>
     <artifactId>mssql-jdbc</artifactId>
     <version>8.4.1.jre8</version>
</dependency>