我在用
Microsoft SQL Server Enterprise:基于核心的授权(64位)版本12.0.4100.1
我有一个代码,它创建了许多非持久内存优化表,将它们用于某些事情,并在不再需要时删除它们。
然而,似乎被丢弃的表仍然在消耗RAM,因为如果我运行
SELECT pool_id, Name, min_memory_percent, max_memory_percent, max_memory_kb/1024 AS max_memory_mb,
used_memory_kb/1024 AS used_memory_mb, target_memory_kb/1024 AS target_memory_mb
FROM sys.dm_resource_governor_resource_pools
WHERE Name='InMemoryObjects'我得到以下信息:
pool_id Name min_memory_percent max_memory_percent max_memory_mb used_memory_mb target_memory_mb
256 InMemoryObjects 50 50 380003 233239 380003注意"used_memory_mb“列有多高。在我运行此操作时,服务器中没有内存优化的表,因此我想,它必须是来自删除的内存优化表的数据,这些表仍在以某种方式占用RAM。
同样的,当我跑的时候
SELECT type, name, memory_node_id, pages_kb/1024 AS pages_MB
FROM sys.dm_os_memory_clerks WHERE type LIKE '%xtp%'我得到以下输出:
type name memory_node_id pages_MB
MEMORYCLERK_XTP Default 0 1055
MEMORYCLERK_XTP DB_ID_19 0 6
MEMORYCLERK_XTP DB_ID_33 0 6
MEMORYCLERK_XTP DB_ID_41 0 56
MEMORYCLERK_XTP DB_ID_47 0 0
MEMORYCLERK_XTP DB_ID_32 0 233240
MEMORYCLERK_XTP Default 1 0
MEMORYCLERK_XTP Default 64 0看到DB_ID_32如何占用相同的240 up内存了吗?
我需要一些办法来解决这个问题。当我运行多个代码实例时,会得到“资源池'InMemoryObjects‘中没有足够的系统内存来运行此查询”。所以我认为这个内存必须被绑起来,当它满的时候不会释放它自己。资源池'InMemoryObjects‘仅仅是为这一段代码创建的,除了该代码创建的对象(随后被删除)之外,整个服务器中没有其他内存优化对象。它创建的内存优化表都相当小(每个表只有几gb )。
我知道垃圾收集器应该每分钟运行一次,但是从数据库中存在任何优化的内存表到现在已经超过一天了,而且使用的内存丝毫没有减少。我尝试过强制垃圾收集、检查点、重置统计等,但是没有能够恢复这个内存。
我发现唯一有效的方法是让整个数据库离线,并将其恢复正常。但是我不能每次运行代码时都这样做,所以我需要一个更好的解决方案。
任何想法都会受到极大的赞赏。谢谢!
发布于 2017-03-06 20:06:26
我觉得这可能是个原因。但我很惊讶强制垃圾收集没能捡起来。来自内存中垃圾回收的MSDN文档:
用户事务提交后,它将标识与其运行的调度程序关联的所有排队项,然后释放内存。如果调度程序上的垃圾收集队列为空,它将搜索当前NUMA节点中的任何非空队列。如果存在较低的事务活动和内存压力,则主垃圾收集线程可以访问任意队列中的垃圾收集行。如果在删除大量行之后没有事务活动,并且没有内存压力,则在事务活动恢复或内存压力存在之前,将不会垃圾收集已删除的行。
https://msdn.microsoft.com/en-us/library/dn643768.aspx
可以尝试垃圾收集吗?我想我在某个地方读到了数据库必须拥有的内存中优化的文件组使用filestream技术。别引用我的话。
https://stackoverflow.com/questions/42633835
复制相似问题