当一个递归方法的调用深度超过运行时堆栈的最大深度时,会引发 “StackOverflowException” 异常,这是 .NET 平台运行时所做的一种保护措施,以避免系统崩溃。也就是说,方法的递归调用过程中引用了太多的堆栈内存,导致堆栈溢出。
解决方法主要有两种:
- 更改程序的设计或算法,减少或消除递归算法的使用或减少参数或变量的使用,或减少递归深度,以避免堆栈溢出的问题。
public int ComputeFibonacci(int num)
{
if(num <= 1) return num;
return ComputeFibonacci(num - 1) + ComputeFibonacci(num - 2);
}
//上述方法采用递归方式求斐波那契数列,如果 num 值较大,则会引发 "StackOverflowException" 异常。可以改用迭代方式实现。
public int ComputeFibonacci(int num)
{
if(num <= 1) return num;
int first = 0, second = 1, result = 0;
for(int i = 2; i <= num; i++)
{
result = first + second;
first = second;
second = result;
}
return result;
}
- 增加栈空间的大小,可以使用 “App.config” 文件来设置栈空间的大小。
<configuration>
<runtime>
<customErrors mode="Off"/>
<gcAllowVeryLargeObjects enabled="true"/>
<disableAllSecurityTypes enabled="false"/>
<legacyUnhandledExceptionPolicy enabled="false"/>
<startup>
<supportedRuntime version="v4.0" sku=".NETFramework,Version=v4.7.2"/>
<!-- 默认堆栈大小是 1MB,可以适当增大 -->
<AppContextSwitchOverrides value="Switch.System.Runtime.Serialization.SerializationGuard.CatchExceptions=true"/>
<AppContextSwitchOverrides value="Switch.System.Threading.Thread.Tasks.Serialization.CrossAppDomainArraySerialization=true"/>
<AppContextSwitchOverrides value="Switch.System.Diagnostics.IgnorePortablePDBsInStackTraces=true"/>
<AppContextSwitchOverrides value="Switch.System.Diagnostics.Tracing.ThrowOnEventWriteErrors=true"/>
<AppContextSwitchOverrides value="Switch.System.IO.UseLegacyPathHandling=false"/>
<AppContextSwitchOverrides value="Switch.System.Security.Cryptography.Xml.UseSha256XmlEncoding=true"/>
<AppContextSwitchOverrides value="Switch.System.Data.SqlClient.DisablePrepareOnFirstPreparedStatementExecution=false"/>
<AppContextSwitchOverrides value="Switch.System.Data.SqlClient.EnableRetryLogic=false"/>
<AppContextSwitchOverrides value="Switch.System.Data.SqlClient.DisableStatementPooling=false"/>
<AppContextSwitchOverrides value="Switch.System.Security.Authentication.SecureSocketsExtensions.NetworkingCbcRecordSplitting=true"/>
<AppContextSwitchOverrides value="Switch.System.Security.Cryptography.AesCryptoServiceProvider.DeprecateAesManaged=false"/>
<AppContextSwitchOverrides value="Switch.System.Security.Cryptography.EncryptedXml.UseDomForEncryptedXml=false"/>
<AppContextSwitchOverrides value="Switch.System.Security.Cryptography.SHA256CryptoServiceProvider.AesNi=false"/>
<AppContextSwitchOverrides value="Switch.System.Security.Cryptography.ECDiffieHellman.UseLegacyImplementation=false"/>
<AppContextSwitchOverrides value="Switch.System.Web.Http.Cors.DisableAsyncSupport=false"/>
<AppContextSwitchOverrides value="Switch.System.Security.Cryptography.X509Certificates.ECDsaCertificateExtensions.UseLegacyCertificateDialog=false"/>
<AppContextSwitchOverrides value="Switch.System.Security.Cryptography.Xml.EncryptedXmlThrowOnDuplicateId=false"/>
</startup>
</runtime>
</configuration>