此产品的文档集力求使用非歧视性语言。在本文档集中,非歧视性语言是指不隐含针对年龄、残障、性别、种族身份、族群身份、性取向、社会经济地位和交叉性的歧视的语言。由于产品软件的用户界面中使用的硬编码语言、基于 RFP 文档使用的语言或引用的第三方产品使用的语言,文档中可能无法确保完全使用非歧视性语言。 深入了解思科如何使用包容性语言。
思科采用人工翻译与机器翻译相结合的方式将此文档翻译成不同语言,希望全球的用户都能通过各自的语言得到支持性的内容。 请注意:即使是最好的机器翻译,其准确度也不及专业翻译人员的水平。 Cisco Systems, Inc. 对于翻译的准确性不承担任何责任,并建议您总是参考英文原始文档(已提供链接)。
本文档介绍内存分配故障(MALLOCFAIL)的症状和可能原因,以及如何解决这些问题的详细信息。
本文档没有任何特定的要求。
本文档中的信息基于以下软件和硬件版本:
所有的 Cisco IOS® 软件版本
所有 Cisco 路由器
注:本文档不适用于使用CatOS或MGX平台的Cisco Catalyst交换机。
本文档中的信息都是基于特定实验室环境中的设备编写的。本文档中使用的所有设备最初均采用原始(默认)配置。如果您的网络处于活动状态,请确保您了解所有命令的潜在影响。
有关文档规则的详细信息,请参阅 Cisco 技术提示规则。
内存分配故障意味着:
路由器使用了所有可用内存(临时或永久),或者
内存分成小片段,以致路由器找不到可用的块。处理器内存(由Cisco Internet Operating System [Cisco IOS]使用)或数据包内存(由传入和传出数据包使用)可能会发生这种情况。
内存分配故障的症状包括但不限于:
控制台或日志消息:“%SYS-2-MALLOCFAIL: Memory allocation of 1028 bytes failed from 0x6015EC84, Pool Processor, alignment 0”
拒绝 Telnet 会话
无论在控制台上键入什么命令,都将显示 show processor memory 命令
一些 show 命令没有输出
“Low on memory”消息
控制台消息“Unable to create EXEC - no memory or too many processes”
路由器挂起,控制台没有响应。
当路由器内存不足时,在某些情况下将无法通过 Telnet 连接到路由器。此时,务必访问控制台端口,以便收集数据进行故障排除。但是,当您连接到控制台端口时,您可以看到以下内容:
%% Unable to create EXEC - no memory or too many processes
如果您看到上一消息,则表示没有足够的可用内存来连接控制台。您可以采取一些步骤通过控制台来捕获数据。如果您帮助路由器释放一些内存,控制台可以响应,然后您可以从路由器捕获必要的数据以进行故障排除。
注意:如果在路由器上配置了边界网关协议(BGP),则可以参考Achieving Optimal Routing and Reduce BGP Memory Consumption来减少与此过程相关的内存消耗。
以下是当控制台端口处于极低内存条件下时尝试捕获数据的步骤:
将 LAN 和 WAN 电缆与路由器的接口断开。这可能导致路由器停止传递数据包。
重新检查控制台。您是否能够得到响应并执行命令?几分钟后,必须有足够的可用内存以允许控制台做出响应。
从特权 EXEC 模式 (Router#) 收集所需信息。至少要收集以下命令的完整输出:show memory allocating-process totals(或show memory summary if show memory allocating-process totals不可用)、show logging ,如果可能,请show technical-support。
收集必要的数据之后,重新连接所有 LAN 和 WAN 链路,并继续监控路由器的内存使用情况。
当您执行show logging命令时,您必须看到如下内容:
%SYS-2-MALLOCFAIL: Memory allocation of [X] bytes failed from 0x6015EC84, pool [Pool], alignment 0 -Process= "[Process]" ipl= 6, pid=5
[X]= 路由器尝试分配的字节数,但找不到足够的可用内存执行该操作
[Pool]指示处理器内存(“池处理器”)或数据包内存(“池I/O”)是否受到影响。高端路由器(7000和7500系列)的缓冲区位于主动态随机访问存储器(DRAM)中,因此数据包内存不足可被报告为“池处理器”。7200系列和通用接口处理器(VIP)卡还可以报告数据包内存的池协议控制信息(“池PCI”)中的错误。
[Process] 指受内存不足影响的进程。
已知问题
从闪存或网络引导加载大型 Cisco IOS 软件时的已知 70x0 问题
通常,MALLOCFAIL错误是由安全问题(例如网络中运行的蠕虫或病毒)引起的。如果最近没有对网络进行任何更改(如升级 Cisco IOS 路由器),则安全问题尤其可能是导致故障的原因。通常,配置更改(例如向访问列表添加其他行)可以减轻此问题的影响。思科产品安全建议和通知页面包含有关检测最可能的原因和具体解决方法的信息。
有关其他信息,请参阅:
首先,检查下载软件区域,了解您运行的功能集和版本的最小内存大小。确保内存是足够的。Cisco.com上的内存要求是在大多数公司网络中正确运行路由器所需的最小建议大小。实际内存要求因协议、路由表和流量模式而异。
注意:只有思科注册用户才能访问思科内部信息和工具。
如果您从Cisco设备获得show memory allocating-process totals命令、 show memory summary命令或show technical-support命令(在启用模式下)的输出,则可以使用输出解释程序显示潜在问题和解决方法。
注意:只有思科注册用户才能访问思科内部信息和工具。
当进程请求或分配内存,然后在执行该任务时忘记释放(取消分配)内存时,就会发生内存泄漏。结果,在重新加载路由器之前,内存块将被一直保留。随着时间的推移,该进程分配的内存块会越来越多,直到没有可用内存。根据此时内存不足情况的严重性,您唯一的选择是重新加载路由器使其重新运行。
这是Cisco Internet Operating System(Cisco IOS)Bug。要消除此漏洞,请升级到您的版本系列中的最新版本,例如,如果您运行Cisco IOS软件版本11.2(14),请升级到最新的11.2(x)映像。
如果这不能解决问题,或者如果您不想升级路由器,请在一段时间内定期输入show processes memory命令(例如,每隔几小时或几天输入一次,具体取决于您的泄漏是快是慢)。检查可用内存是否继续减少并且从不返回。可用内存消失的速率视导致泄露的事件的发生频率而定。由于内存从未被释放,因此如果随时间拍摄内存快照,您可以跟踪使用内存的进程。请记住,不同的进程会根据需要分配和取消分配内存,因此您可以看到差异,但随着泄露的继续,您必须看到一个持续消耗更多内存的进程。
注:边界网关协议(BGP)或开放最短路径优先(OSPF)路由器等进程使用超过1兆字节的内存是正常的;这并不意味着它们正在泄漏。
要确定消耗更多内存的进程,请比较该时间间隔内show processes memory命令的“保持”列。有时,您可以非常明显地发现一个进程占用了数兆字节的内存。有时,需要创建多个快照以便找到起因。如果丢失了大量内存,请收集 show memory allocating-process totals 命令或 show memory summary 命令,以便进行其他故障排除。然后,与 Cisco 技术支持中心 (TAC) 联系,并且提供所收集的信息以及路由器的 show technical-support 汇总。
通过命令输出解释程序工具,可以接收对 show memory allocating-process totals 命令或 show memory summary 输出的分析。
注意:只有思科注册用户才能访问思科内部信息和工具。
下表列出了 show memory summary 命令输出的前三行:
Router>show memory summary Head Total (b) Used (b) Free (b) Lowest (b) Largest (b) Processor 60AB4ED0 5550384 2082996 3467388 3464996 3454608 I/O 40000000 16777216 1937280 14839936 14839936 14838908
Total = 系统映像加载并建立其数据结构后的可用内存总量。
Used = 当前分配的内存量。
Free = 当前可用的内存量。
Lowest = 路由器自上次引导后记录的最小可用内存量。
Largest = 当前可用的最大可用内存块。
show memory allocating-process totals 命令包含与 show memory summary 命令前三行相同的信息。
下面是您可以从 show processes memory 命令输出了解到的信息:
Router>show processes memory Total: 3149760, Used: 2334300, Free: 815460 PID TTY Allocated Freed Holding Getbufs Retbufs Process 0 0 226548 1252 1804376 0 0 *Initialization* 0 0 320 5422288 320 0 0 *Scheduler* 0 0 5663692 2173356 0 1856100 0 *Dead* 1 0 264 264 3784 0 0 Load Meter 2 2 5700 5372 13124 0 0 Virtual Exec 3 0 0 0 6784 0 0 Check heaps 4 0 96 0 6880 0 0 Pool Manager 5 0 264 264 6784 0 0 Timers 6 0 2028 672 8812 0 0 ARP Input 7 0 96 0 6880 0 0 SERIAL A' detect 8 0 504 264 7024 0 0 ATM ILMI Input 9 0 0 0 6784 0 0 ILMI Process 10 0 136 0 6920 0 0 M32_runts pring 11 0 136 0 6920 0 0 Call drop procs 12 0 340 340 12784 0 0 ATMSIG Timer 13 0 445664 442936 13904 0 0 IP Input 14 0 2365804 2357152 17992 0 0 CDP Protocol 15 0 528 264 7048 0 0 MOP Protocols 16 0 188 0 9972 0 0 IP Background 17 0 0 1608 6784 0 0 TCP Timer 18 0 5852116 0 14236 0 0 TCP Protocols
Allocated = 自路由器引导后进程已分配的总字节数。
Freed = 此进程已释放的总字节数。
Holding = 此进程当前占有的总字节数。该列对于进行故障排除是最重要的,因为它显示了分配给此进程的实际内存量。保持不必等于分配减释放,因为某些程序分配内存块以后将通过其他程序返回到空闲池。
*dead* 进程不是真正的进程。它用于说明在已终止的另一个进程的上下文下分配的内存。分配给此进程的内存由内核回收,并在必要时由路由器本身返回到内存池。这是Cisco IOS处理内存的方式。如果创建内存块的进程退出(不再运行),该内存块将被视为无用块。每个块都会记录创建它的进程的地址和 PID。在定期内存计数期间,如果调度程序从块pid中查找到的进程与块记得的进程不匹配,则该块将被标记为停机。
因此,标记为属于 *Dead* 进程的内存分配受不再运行的进程所控。存在大量这样状态的内存块是正常的。示例如下:
当在Telnet会话中配置网络地址转换(NAT)时,分配内存。Telnet 进程 ("Virtual Exec") 占用该内存。终止此进程后,NAT 配置的内存仍在使用中。这是通过*dead*进程显示的。
您可以看到内存分配到的环境 show memory dead
命令,在“What”列下:
Router#show memory dead Head Total(b) Used(b) Free(b) Lowest(b) Largest(b) I/O 600000 2097152 461024 1636128 1635224 1635960 Processor memory Address Bytes Prev. Next Ref PrevF NextF Alloc PC What 1D8310 60 1D82C8 1D8378 1 3281FFE Router Init 2CA964 36 2CA914 2CA9B4 1 3281FFE Router Init 2CAA04 112 2CA9B4 2CAAA0 1 3A42144 OSPF Stub LSA RBTree 2CAAA0 68 2CAA04 2CAB10 1 3A420D4 Router Init 2ED714 52 2ED668 2ED774 1 3381C84 Router Init 2F12AC 44 2F124C 2F1304 1 3A50234 Router Init 2F1304 24 2F12AC 2F1348 1 3A420D4 Router Init 2F1348 68 2F1304 2F13B8 1 3381C84 Router Init 300C28 340 300A14 300DA8 1 3381B42 Router Init
如果检测到内存泄漏,并且*Dead*进程似乎是消耗内存的进程,则包括 show memory dead
在提供给思科TAC的信息中。
这是进行验证最困难的原因之一。该问题表现为存在大量可用内存,但“Lowest”列中的值很小。在这种情况下,正常事件或异常事件(例如,路由存在很大不稳定性)会导致路由器在内存已用完的短时间内使用异常大量的处理器内存。在该期间,路由器将报告 MALLOCFAIL。可能不久之后,内存释放并问题消失(例如,网络稳定)。内存不足也可能是由多种因素造成的,例如:
消耗了大量内存的内存泄漏和网络不稳定性,将促使可用内存变为零。
路由器没有足够的内存来开始运行,但只有在发生罕见的网络事件时才发现该问题。
如果路由器未重新启动,请输入 show memory allocating-process totals
命令(或 show memory summary
如果 show memory allocating-process totals
不可用)并查看前三行。日志消息可以提供有关哪个进程消耗大量内存的线索:
如果使用大量内存归结于:
正常事件,解决方案是安装更多的内存。
罕见或异常事件,请解决相关问题。然后,您可以决定为未来的“保险”购买额外内存。
这种情况意味着一个进程占用了大量的处理器内存,然后释放了大部分或全部内存,并留下内存碎片仍然由这个进程分配,或由其他进程分配,在整个问题期间分配内存。如果相同事件多次发生,内存可能会分片成非常小的块,以至于所有需要更大内存块的进程都不能获得它们需要的内存量。这会影响路由器的操作,以至于您无法连接到路由器,并且在内存碎片严重时收到提示。
此问题的特征是IP地址的“最大”列(小于20,000字节)中的值较低 show memory
命令,但“释放”列中的值已足够(1MB或更多),或者这两列之间存在其他差异。当路由器的内存非常低时,就会发生这种情况,因为Cisco IOS中没有分段例程。
如果您怀疑内存分段,请关闭一些接口。这样可以释放分片块。如果正常工作,内存将正常工作,您只需添加更多内存即可。如果关闭接口没有帮助,则可能是Bug。最佳措施是与 Cisco 支持代表联系,并提供您所收集的信息。
此情况可以通过错误消息中的进程确定。如果进程列为<中断级别>(如下一示例所示),则内存分配故障是由软件问题引起的。
"%SYS-2-MALLOCFAIL: Memory allocation of 68 bytes failed from 0x604CEF48, pool Processor, alignment 0-Process=, ipl= 3"
这是Cisco Internet Operating System(Cisco IOS)Bug。您可以使用Bug工具包搜索与此问题匹配的软件Bug ID。确定软件 Bug 之后,请升级到包含修复程序的 Cisco IOS 软件版本,以解决该问题。
注意:只有思科注册用户才能访问思科内部信息和工具。
基于每个用户使用访问列表时,访问列表会消耗大量内存。这些访问列表太大,无法按照微型访问控制列表 (ACL) 分类,现在已被编译为 Turbo ACL。每次发生这种情况时,TACL 进程都必须启动并处理新的 ACL。这可能导致根据编译时间和可用处理时间允许或拒绝的流量。
必须将已编译的 ACL 发送到 XCM。如果只有有限的可用空间,则一旦内存用尽这些空间,就会显示控制台消息并启动内存碎片整理程序。
解决方法如下:
使用简明的ACL,减少可编译为微型ACL的应用控制引擎(ACE)数量,同时减少用于编译的内存消耗和进程功率。
在路由器上使用通过 RADIUS 属性 filterID 引用的预定义 ACL。
当 7000 路由处理器 (RP) 从闪存中引导映像时,它会首先加载 ROM 映像,然后再将闪存映像加载到内存中。旧RP只有16 MB的内存,而高于11.0版的Cisco IOS软件版本的企业版在解压缩时大于8 MB。因此,当您从ROM加载映像,然后加载闪存时,7000 RP可能会耗尽内存,或者内存会在启动过程中分段,因此路由器会收到与内存相关的错误消息。
解决方案是从配置寄存器启用快速引导,以使 RP 在 ROM 中只加载 Cisco IOS 软件映像的最小子集,然后从闪存加载整个 Cisco IOS 软件。要启用快速启动,请将配置寄存器设置为0x2112。这还可以加快引导过程。
使用CiscoWorks的UT Discovery功能,可能导致某些路由器上的可用内存量变得非常小。show proc memory命令可指示“IP输入”进程占用大量内存。这是“IP input”进程的正常进程或异常进程使用大量内存问题的特殊情况,该问题也可能造成内存分段问题,前提是内存不足状况导致内存发生分段。
UT 发现功能使网络管理站可以发出 ping 扫描,以查找每个已发现子网中的所有 IP。内存问题是由路由器上IP快速交换缓存的增大引起的,因为每个新目标都会创建新的缓存条目。由于用于缓存中条目的掩码取决于如何对其进行子网划分,主网络中存在32位掩码的地址(例如环回地址)会导致该网络的所有条目使用32位掩码。这会导致创建大量缓存条目并使用大量内存。
最佳解决方案是禁用 UT 发现。您可以通过以下步骤执行此操作:
转到 C:\Program Files\CSCOpx\etc\cwsi\ANIServer.properties。
添加“UTPingSweep=0”。
重新启动 ANI。
这会导致“用户跟踪”(User Tracking)表错过某些终端服务器或过期(另一个称为“用户注册工具”(User Registration Tool)的思科应用程序可能存在此问题,该应用程序依赖于UT),但不会影响仅使用SNMP流量的园区发现。CEF交换还可以改善这种情况(使用CEF时,IP缓存是在启动时根据路由表创建的)。有关 CEF 和其他可用交换路径的详细信息,请参阅如何为您的网络选择最佳路由器交换路径。
许多其他应用程序也可能造成类似的内存不足情况。在大多数情况下,该问题的根本原因不是路由器,而是应用程序本身。通常,您必须通过检查应用的配置来防止这些数据包风暴。
一些路由器(例如,2600、3600 和 4000 系列)要求使用最低数量的 I/O 内存来支持某些接口处理器。
如果路由器共享内存不足,即使重新加载后也是如此,您也可以通过物理方式移除接口来解决此问题。
在3600系列路由器上,全局配置命令 memory-size iomem i/o-memory-percentage
可用于重新分配用于I/O内存和处理器内存的DRAM百分比。i/o-memory-percentage允许的值为10、15、20、25(默认值)、30、40和50。I/O 内存至少需要 4 MB 内存。
为了对此问题进行故障排除,请参阅:
如果您有 show buffers
命令或 show technical-support
命令(在启用模式下),您可以使用Output Interpreter显示潜在问题和解决方法。
注意:只有思科注册用户才能访问思科内部信息和工具。
当进程使用缓冲区完成时,该进程必须释放缓冲区。当代码忘记处理缓冲区或在数据包完成之后忘记释放缓冲区时,就会发生缓冲区泄漏。因此,随着越来越多的数据包滞留在缓冲区中,缓冲池将继续增长。您可以使用 show buffers
命令。某些公共缓冲池必须异常大,而可用的缓冲极少。重新加载后,您可以看到可用缓冲区的数量永远不会接近总缓冲区的数量。
Output Interpreter(输出解释程序)工具允许您接收对 show buffers
输出。
在下面的示例中,中间缓冲区受到了影响。此 show buffers
命令指示使用了近8094个缓冲区,但没有释放这些缓冲区(8122总减去28个空闲缓冲区):
Public buffer pools: Small buffers, 104 bytes (total 50, permanent 50): 50 in free list (20 min, 150 max allowed) 403134 hits, 0 misses, 0 trims, 0 created 0 failures (0 no memory) Middle buffers, 600 bytes (total 8122, permanent 200): 28 in free list (10 min, 300 max allowed) 154459 hits, 41422 misses, 574 trims, 8496 created Big buffers, 1524 bytes (total 50, permanent 50): 50 in free list (5 min, 150 max allowed) 58471 hits, 0 misses, 0 trims, 0 created 0 failures (0 no memory) VeryBig buffers, 4520 bytes (total 10, permanent 10): 10 in free list (0 min, 100 max allowed) 0 hits, 0 misses, 0 trims, 0 created 0 failures (0 no memory) Large buffers, 5024 bytes (total 0, permanent 0) 0 in free list (0 min, 10 max allowed) 0 hits, 0 misses, 0 trims, 0 created 0 failures (0 no memory) Huge buffers, 18024 bytes (total 0, permanent 0): 0 in free list (0 min, 4 max allowed) 0 hits, 0 misses, 0 trims, 0 created 0 failures (0 no memory)
这是一个 Cisco IOS 软件 Bug。请升级到您的版本系列中的最新版本,修复已知的缓冲区泄漏 Bug(例如,如果运行的是 Cisco IOS 软件版本 11.2(14),则升级到最新版本的 11.2(x) 映像)。如果这不起作用,或者如果无法升级路由器,请在路由器内存不足时针对问题池发出以下命令。这些命令可显示有关缓冲区内容的其他信息:
show buffer old
显示时间超过一分钟的已分配缓冲区
show buffer pool
(small - middle - big - verybig - large - huge)
显示指定池的缓冲区汇总
show buffer pool
(small - middle - big - verybig - large - huge) dump
显示使用指定池的所有缓冲区的十六进制/ASCII 转储。
有关其他详细信息,请参阅排除缓冲区泄漏故障。
此问题特定于 7500 系列。如果路由器的“快速”内存耗尽,它可以使用其主动态RAM(DRAM)。不需要采取任何操作。
trying
删除前缀条目[IP_address]/[dec](应为[hex],实际为[hex])IPFAST-4-RADIXDELETE: Error trying to delete prefix entry [IP_address]/[dec](expected [hex], got [hex])错误消息表明内存中的路由器快速交换缓存表已损坏。当路由器尝试清除正常进程下的缓存表或 clear ip cache
命令,系统由于内存损坏而无法删除条目。当路由器无法删除此类条目时,会报告IPFAST-4-RADIXDELETE消息。
为了解决缓存表内存损坏问题,需要对路由器进行硬重启。重新启动可以再次切割系统内存结构,并允许快速缓存重建无损坏。
%SYS-2-CHUNKEXPANDFAIL的原因:无法扩展TACL位图的块池。No memory available 错误消息的原因是,没有为增加指定块池留下足够的处理器内存。它可能是由于进程异常运行造成的。
解决方法是定期捕获(根据问题的频率)这些命令的输出,以便监控路由器的内存使用情况:
show processes memory sorted
show memory statistics
show memory allocating-process totals
使用以下步骤:
检查 Cisco IOS 软件发行版本或功能集的内存要求。
如有可能,升级到您的版本系列中的最新 Cisco IOS 软件发行版本。
检查正常进程或异常进程使用的大量内存。如有必要,请添加更多的内存。
检查这是否是泄漏或分段(高端路由器的缓冲区泄漏)。
收集相关信息并与 TAC 联系。
使用以下步骤:
检查共享内存要求(请参阅“接口没有足够的共享内存”)。
如有可能,升级到您的版本系列中的最新 Cisco IOS 软件发行版本。
确定哪个缓冲池受到影响,收集相关信息,然后与 Cisco TAC 联系。
版本 | 发布日期 | 备注 |
---|---|---|
2.0 |
19-Jan-2023 |
更新格式,固定CCW警报。重新认证。 |
1.0 |
02-Nov-2001 |
初始版本 |