如何找到已提交内存越来越大的原因?

本文探讨了Windows 10系统中内存泄漏问题,用户发现提交内存剧增但具体进程不明。通过AIDA64分析和输入法测试揭示内存管理问题,以及如何通过设置虚拟内存来暂时缓解。

最近经常提示内存不足,发现任务管理器中已提交内存变得很大,PageFile也很大。

但任务管理器的详细信息里面查看所有进程的提交内存都不是很大,加起来远远达不到任务管理器性能页签里面的已提交内存。

网上一搜,好像也有很多人遇到Win8的这个问题,但好像都没有得到解决。

不知道如何才能知道是什么软件制造了那么多已提交内存。

使用干净的方式启动Windows好像也没有效果,刚启用的时候不大,用着用着就越来越大。

如果在已提交内存比较大的时候对内存做个Dump能看出是什么程序在提交内存么?

我现在用NotMyFault工具已经得到了这样的一个内存Dump文件,但不知道如何才能看出已提交内存是谁消耗的。

网友测试1:

aida64里面,1就是已用物理内存,3是已用页面文件,2相当于已提交。

刚开机时一般1+3=2.

运行大量占用显存的程序时可以观察到1+3+(已使用显存)=2.貌似系统使用显存时会提交同样大小的内存空间。

当有程序的提交内存比工作集大很多时:1+3+(已使用显存+程序提交内存)=2.

当运行虚拟机时:1+3+(已使用显存+程序提交内存+分配给虚拟机的内存)=2.

我猜测有些情况下:1+3+(已使用显存+程序提交内存……+某种缓存+泄漏掉的内存)=2.

上述等式里面括号中的部分无限增大无法释放时,就出现了你所说的这个问题。我现在是chrome关闭gpu加速,superfetch打开,使用板载显卡。从我截的图可以看到,现在已用物理内存加上已用页面文件才2.6g左右,但已提交已经达到5g,这个数字再继续涨的话,说明问题还是存在,相当于内存泄漏。问题到底是怎样的,还需要继续试验。

 

本文的问题其实很简单。如果你有了解一点点操作系统原理的话你就能够很容易理解这个问题。

我们先定义几个概念:

1. 物理内存,也就是我们常常见到的内存条

2. 虚拟内存(磁盘上的 pagefile),在Linux下面叫做swap,这个是一个特定的文件或者设备,当物理内存不够的时候就会把内存保存(交换)到虚拟内存

3. 地址空间,物理内存的大小加上虚拟内存的大小就是地址空间

4. 提交的内存(commited memory),这是程序向windows请求的内存,一旦程序请求分配,windows就从地址空间里面分配一段地址。但是注意,实际上这里只分配了地址,没有真正分配内存。所有的提交的内存大小总和不允许超过地址空间。实际上使用的内存往往远远小于提交的内存。

某些程序往往会预先向windows请求大量的内存,但是实际上又不使用,最终导致提交的内存很大,超过地址空间,导致其他程序请求内存失败。而这个时候内存还是大量的空着的。这就是本文问题的所在。

如果要真的了解和学习操作系统,还是用 Linux 来的比较好。

问题原因:

我经常发现 Commit Size of Memory 增长到 20GB 左右,W​​indows 给了我警告。但是我找不到任何使用大量内存提交大小的进程。

这是一个很容易重现的错误,但在 Win 10 内核中根深蒂固。 

1) 打开任务管理器,转到性能选项卡,注意“已提交”数字。 

2)打开记事本,切换到中文拼音输入法,继续输入“s”,变成水水水水水水水。

每次可以一次输入15个汉字。继续执行大约 15 * 21 个字符,您将看到“已提交”内存增加了 100MB。 

3)您可以继续这样做,直到您的虚拟内存耗尽。直到注销您的 Win 10 帐户,内存才会释放。 

更有趣的是,您将无法找到提交这些泄漏内存的单个程序。在“详细信息”选项卡中,所有提交大小的总和远小于性能选项卡中报告的提交数量。 

我想知道这是否是一个深深植根于内核内存管理中的错误。正是 IME 非常清楚地显示了它。 

当我使用SurfacePro、SurfacePro2、SurfacePro3、SurfacePro4等所有电脑时,都被这个bug困扰。

windows 10周年更新后,发现这个问题仍然没有解决,只是“缓解”了。

原来的情况是

“微软拼音输入法单次最多输入19个汉字,大概输入7-8轮,committed 就会增加100M。”

现在的情况是,需要输入15/16轮,committed内存增加100m。  bug造成的问题依旧,只是之前可能电脑用了一天后,我的内存报警(手动设定了虚拟内存/页面文件的上限),现在是一天半后报警。    还是只能删除自带中文输入法,继续用第三方。

当我停止“\Microsoft\Windows\TextServicesFramework”中名为“MsCtfMonitor”的计划任务时,系统的提交大小释放了很多。

我不知道为什么这个错误大约两年没有修复。

凑合的解决方案:

自从win10自动升级后,我电脑上这个问题变的越来越严重了,浏览器看个网页或者随便启动啥软件都要崩溃,后来才发现是已提交内存越来越大。因此我的操作是手动设置虚拟内存,昨天设置了40G虚拟内存,结果用了一天,直到昨天晚上才崩溃。今天把虚拟内存改为80G,到现在为止还没出现内存不足的问题。。。

<think>我们正在处理用户关于SQL Server内存占用持续增长的问题。根据用户提供的引用和问题,我们需要分析可能的原因并提供解决方案。 首先,根据引用[1]和[3],我们知道SQL Server会尽可能使用内存来缓存数据,以提高性能。但内存持续增长可能导致系统资源紧张。 可能的原因: 1. SQL Server的内存使用没有上限设置,导致其不断占用可用内存。 2. 存在内存泄漏(虽然较少见,但某些情况下可能发生)。 3. 查询效率低下,导致需要更多的内存来处理(例如,量的排序、哈希操作等)。 4. 内存压力来自其他方面,如锁、缓存等。 解决方案: 1. 设置最服务器内存:避免SQL Server占用所有系统内存。 ```sql EXEC sys.sp_configure N'max server memory (MB)', N'<desired_value>'; -- 例如,设置为物理内存的70-80%,留出部分给操作系统和其他应用 RECONFIGURE; ``` 注意:需要根据实际内存小调整。 2. 监控内存使用情况:使用性能计数器(如引用[3]提到的Page Faults/sec)和动态管理视图(DMV)来监控。 - 使用以下查询查看内存使用情况: ```sql SELECT (physical_memory_in_use_kb/1024) AS [Memory_usedby_Sqlserver_MB], (locked_page_allocations_kb/1024) AS [Locked_pages_allocations_MB], (total_virtual_address_space_kb/1024) AS [Total_VAS_MB], process_physical_memory_low, process_virtual_memory_low FROM sys.dm_os_process_memory; ``` 3. 检查内存消耗的查询:通过DMV查找消耗内存较多的查询。 ```sql SELECT session_id, request_id, start_time, status, command, sql_handle, database_id, user_id, connection_id, blocking_session_id, wait_type, wait_time, last_wait_type, wait_resource, open_transaction_count, -- 其他相关列 st.text AS [SQL Text], qp.query_plan FROM sys.dm_exec_requests CROSS APPLY sys.dm_exec_sql_text(sql_handle) AS st OUTER APPLY sys.dm_exec_query_plan(plan_handle) AS qp ORDER BY [Memory_usedby_request] DESC; -- 注意:这里没有直接的内存使用列,需要结合其他DMV ``` 实际上,我们可以使用`sys.dm_exec_query_memory_grants`来查看正在申请内存的查询(特别是需要排序或哈希操作的查询): ```sql SELECT session_id, request_id, scheduler_id, dop, request_time, grant_time, requested_memory_kb, granted_memory_kb, required_memory_kb, used_memory_kb, max_used_memory_kb, query_cost, timeout_sec, resource_semaphore_id, queue_id, wait_order, is_next_candidate, wait_time_ms FROM sys.dm_exec_query_memory_grants WHERE grant_time IS NOT NULL; -- 已经获得内存授权的查询 ``` 4. 检查缓存:过多的缓存计划可能导致内存占用高。可以定期清理缓存(谨慎使用): ```sql DBCC FREESYSTEMCACHE ('ALL') WITH MARK_IN_USE_FOR_REMOVAL; ``` 但注意,这可能会导致性能暂时下降,因为需要重新编译执行计划。 5. 索引优化:确保表有合适的索引,减少查询的内存需求(引用[1]提到索引维护的重要性)。 6. 检查内存泄漏:虽然SQL Server自身内存管理良好,但某些第三方扩展或自定义代码可能导致内存泄漏。可以通过重启SQL Server服务来观察内存是否重新增长来初步判断。 7. 使用SQL Server性能监控工具(引用[4]):监控内存相关的计数器,例如: - SQL Server: Memory Manager - Total Server Memory (KB):当前SQL Server已提交内存。 - SQL Server: Memory Manager - Target Server Memory (KB):SQL Server理论上可以使用的最内存(根据max server memory设置)。 - 如果Total Server Memory接近Target Server Memory,说明内存使用达到了配置的上限。 - 另外,监控操作系统的内存使用情况(如Available MBytes)以确定整体内存压力。 8. 考虑内存优化表(In-Memory OLTP):如果使用的是SQL Server 2014及以上版本,并且有特定的表频繁访问,可以考虑将表配置为内存优化表,但这需要评估。 9. 更新统计信息:过时的统计信息可能导致查询优化器选择低效的执行计划,从而增加内存使用。定期更新统计信息: ```sql EXEC sp_updatestats; ``` 10. 检查锁和阻塞:长时间的阻塞可能导致查询持有内存资源无法释放(引用[4]提到监控阻塞进程)。 11. 调整工作负载:如果可能,将操作分解为小操作,减少单次内存需求。 总结步骤: 1. 设置最内存限制。 2. 监控内存使用情况,找出内存消耗的查询。 3. 优化查询和索引。 4. 定期维护(更新统计信息,重建索引等)。 5. 监控并分析内存使用模式。 如果以上方法不能解决问题,可能需要进一步分析SQL Server错误日志和系统事件日志(引用[4]),或者考虑升级到最新版本或应用补丁。 最后,注意:SQL Server设计为尽可能使用内存,所以内存使用率高并不一定是问题,除非它导致系统不稳定或性能下降。 §§相关问题§§ 1. 如何设置SQL Server的最内存限制? 2. 如何监控SQL Server的内存使用情况? 3. 如何找出SQL Server中消耗内存最多的查询? 4. 为什么需要定期重建索引?如何操作? 5. SQL Server的内存优化表有什么优缺点?</think>### SQL Server 内存占用持续增长解决方案 SQL Server 内存占用持续增长通常由以下原因引起: 1. **未配置内存上限**:SQL Server 默认会尽可能占用可用内存作为缓存[^1]。 2. **内存泄漏**:第三方扩展、驱动或 SQL Server 自身缺陷导致。 3. **低效查询**:量排序、哈希操作或内存表扫描消耗内存[^3]。 4. **锁竞争**:长时间阻塞导致内存无法释放[^4]。 5. **统计信息过时**:优化器选择低效执行计划。 --- ### 解决方案(按优先级排序) #### 1. **设置最内存限制** ```sql -- 设置最内存为物理内存的70-80%(保留部分给OS) EXEC sys.sp_configure N'max server memory (MB)', N'<数值>'; RECONFIGURE; ``` > 📌 **关键**:避免SQL Server耗尽系统内存,尤其在高并发场景[^1]。 #### 2. **诊断内存使用源头** ```sql -- 查看内存分配详情 SELECT type = CASE WHEN database_id = 32767 THEN 'ResourceDB' ELSE DB_NAME(database_id) END, pages_kb / 1024 AS size_mb FROM sys.dm_os_buffer_descriptors ORDER BY size_mb DESC; -- 检查内存消耗高的查询 SELECT TOP 10 total_logical_reads, execution_count, query_text = SUBSTRING(st.text, (qs.statement_start_offset/2)+1, ((CASE qs.statement_end_offset WHEN -1 THEN DATALENGTH(st.text) ELSE qs.statement_end_offset END - qs.statement_start_offset)/2) + 1) FROM sys.dm_exec_query_stats qs CROSS APPLY sys.dm_exec_sql_text(qs.sql_handle) st ORDER BY total_logical_reads DESC; ``` #### 3. **优化查询与索引** - **重建碎片化索引**: ```sql ALTER INDEX ALL ON <表名> REBUILD; ``` - **添加缺失索引**(根据执行计划建议)。 - **避免 `SELECT *`**,仅查询必要字段。 - **优化排序操作**:减少 `ORDER BY` 对数据集的使用。 #### 4. **监控内存压力指标** 通过性能计数器监控[^3][^4]: - **Memory: Page Faults/sec**:持续高位表明内存瓶颈 - **SQL Server: Buffer Manager - Page life expectancy**:低于300秒需警惕 - **SQL Server: Memory Manager - Memory Grants Pending**:>0 表示内存不足 #### 5. **处理内存泄漏** - 更新至最新 **SQL Server CU补丁**。 - 禁用可疑的第三方扩展(如自定义CLR程序集)。 - 检查错误日志中 `memory clerk` 相关警告。 #### 6. **定期维护** ```sql -- 更新统计信息 EXEC sp_updatestats; -- 清除执行计划缓存(谨慎使用) DBCC FREEPROCCACHE; ``` --- ### 预防措施 1. **启用锁监控**: ```sql -- 检测阻塞链 SELECT * FROM sys.dm_os_waiting_tasks WHERE blocking_session_id <> 0; ``` 2. **配置内存告警**:当 `Total Server Memory` 达到上限的90%时触发警报[^4]。 3. **使用内存优化表**:对高频访问小表启用In-Memory OLTP(需评估兼容性)。 > ⚠️ **注意**:SQL Server设计上会占用可用内存提升性能,需区分"合理缓存"与"异常增长"[^1]。若配置上限后内存仍持续增长,需排查泄漏或查询问题。 ---
评论 7
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值