4、栈溢出
1)溢出情况
a)线程试图提交比保留大小更多的栈内存页
b)没有物理内存也没有虚拟内存可供提交更多的守护页
2、栈溢出后还想继续运行程序,必须重置守护页,可以使用CRT的_resetstkoflw。
不过对于大的数据,可以考虑将某些数据移到堆中。堆栈是有限的,甚至在用户模式下也是如此,如果无法提交堆栈页,会导致堆栈溢出异常。_resetstkoflw 函数可以将系统从堆栈溢出的情况恢复为正常,从而使程序得以继续运行,而不会由于出现异常错误而失败。如果未调用 _resetstkoflw 函数,则在上一个异常后不会显示保护页。当下次发生堆栈溢出时,根本不会显示异常,进程将在没有任何警告的情况下终止。
System.Runtime.CompilerServices.RuntimeHelpers在线程栈空间的探查方面有很大的作用
下面这是这个类的常用方法
EnsureSufficientExecutionStack 确保剩余的堆栈空间足够大,可以执行一般的 .NET Framework 函数。
Equals(Object, Object) 确定指定的 Object 实例是否被视为相等。
ExecuteCodeWithGuaranteedCleanup 使用一个 Delegate 执行代码,同时使用另一个 Delegate 在异常情况下执行附加代码。
GetHashCode(Object) 用作特定类型的哈希函数,适合在哈希算法和数据结构(如哈希表)中使用。
GetObjectValue 将值类型装箱。
InitializeArray 提供从存储在模块中的数据初始化数组的快速方法。
PrepareConstrainedRegions 将代码体指定为受约束的执行区域 (CER)。
PrepareConstrainedRegionsNoOP 指定代码体为受约束的执行区域 (CER),而不执行任何探测。
PrepareContractedDelegate 提供应用程序用来动态准备 AppDomain 事件委托的方法。
PrepareDelegate 指示应准备指定委托以包含在受约束的执行区域 (CER) 中。
PrepareMethod(RuntimeMethodHandle) 准备一个要包含在受约束的执行区域 (CER) 中的方法。
PrepareMethod(RuntimeMethodHandle, RuntimeTypeHandle()) 准备一个要包含在受约束的执行区域 (CER) 中的具有指定实例化的方法。
ProbeForSufficientStack 探测某个数量的堆栈空间,以确保不会在后续的代码块内发生堆栈溢出(假设您的代码仅使用有限适中的堆栈空间)。 建议使用受约束的执行区域 (CER),而不使用此方法。
RunClassConstructor 运行指定的类构造函数方法。
RunModuleConstructor 运行指定的模块构造函数方法。
其中比较常用的是
ProbeForSufficientStack 和PrepareConstrainedRegions
从MSDN中可看出以下细节:
1)PrepareConstrainedRegions
编译器使用此方法来将 catch、finally 和 fault 块标记为受约束的执行区域 (CER)。 标记为受约束的区域的代码必须只调用其他具有高可靠性协定的代码。 它不能分配或虚调用未准备的或不可靠的方法,除非它已准备好处理失败。
请注意,除了 NOP 之外,在对 PrepareConstrainedRegions 方法的调用和 try 块之间不允许使用其他任何中间语言操作码。
受约束的执行区域 (CER) 是创作可靠托管代码的机制的一部分。CER 定义一个区域,在该区域中公共语言运行库 (CLR) 会受到约束,不能引发可使区域中的代码无法完全执行的带外异常。在该区域中,用户代码受到约束,不能执行会导致引发带外异常的代码。PrepareConstrainedRegions 方法必须直接位于 try 块之前,并将 catch、finally 和 fault 块标记为受约束的执行区域。标记为受约束的区域后,代码只能调用其他具有强可靠性约定的代码,而且代码不应分配或者对未准备好的或不可靠的方法进行虚调用,除非代码已经准备好处理错误。CLR 为 CER 中正在执行的代码延迟线程中止。
除批注的 try 块外,受约束的执行区域还以其他形式用于 CLR 中
CLR 会事先准备 CER 以避免出现内存不足的情况。进行事先准备的目的是为了避免 CLR 在实时编译或类型加载时发生内存不足的情况。
CER 中不允许下面的操作:
显式分配。
获取锁。
装箱。
多维数组访问。
通过反射进行的方法调用。
Enter 或 Lock。
安全检查。不执行命令,仅链接命令。
COM 对象和代理的 Isinst 和 Castclass
获取或设置透明代理上的字段。
序列化。
函数指针和委托。
如果您计划使用适当数量的堆栈空间,则使用 try/finally 或 try/catch 块后跟对 RuntimeHelpers.PrepareConstrainedRegions 方法的调用。 如果您正在调用递归方法或计划使用大量堆栈空间,则必须使用 RuntimeHelpers.ExecuteCodeWithGuaranteedCleanup 方法。
可如下构造代码
RuntimeHelpers.PrepareConstrainedRegions()
Try
分配大量堆栈空间的代码
Finally
分配失败后的清理工作或安全分配空间的代码
End Try
下面是msdn中可靠地设置句柄的操作:
要可靠地将句柄设置为指定的预先存在的句柄,必须确保本机句柄的分配,以及该句柄在SafeHandle 对象中的后续记录是原子操作这些操作之间,如果出现任何故障(如线程中止或内存不足异常)都会导致该本机句柄泄漏。 可以使用 PrepareConstrainedRegions 方法确保句柄不会泄漏。
<StructLayout(LayoutKind.Sequential)> _
Structure MyStruct
Public m_outputHandle As IntPtr
End Structure 'MyStruct
NotInheritable Class MySafeHandle
Inherits SafeHandle
' Called by P/Invoke when returning SafeHandles
Public Sub New()
MyBase.New(IntPtr.Zero, True)
End Sub
Public Function AllocateHandle() As MySafeHandle
' Allocate SafeHandle first to avoid failure later.
Dim sh As New MySafeHandle()
RuntimeHelpers.PrepareConstrainedRegions()
Try
Finally
Dim myStruct As New MyStruct()
NativeAllocateHandle(myStruct)
sh.SetHandle(myStruct.m_outputHandle)
End Try
Return sh
End Function
2)ProbeForSufficientStack
探测某个数量的堆栈空间,以确保不会在后续的代码块内发生堆栈溢出(假设您的代码仅使用有限适中(12页栈内存)的堆栈空间)。 建议使用受约束的执行区域 (CER),而不使用此方法。
使用方式是
RuntimeHelpers.ProbeForSufficientStack()
分配或使用栈内存的语句
3)此外
RuntimeHelpers.ExecuteCodeWithGuaranteedCleanup 也很重要
Public Shared Sub ExecuteCodeWithGuaranteedCleanup ( _
code As RuntimeHelpers..::..TryCode, _ backoutCode As RuntimeHelpers..::..CleanupCode, _ userData As Object _
)
从其参数就可以看出它对处理栈溢出的重要性了
code
类型:System.Runtime.CompilerServices.RuntimeHelpers.TryCode
要尝试的代码的委托。
backoutCode
类型:System.Runtime.CompilerServices.RuntimeHelpers.CleanupCode
在发生异常时要运行的代码的委托。
userData
类型:System.Object
要传递给 code 和 backoutCode 的数据
分享到:
相关推荐
最近收集的VB.Net-C#多线程Thread-代理委托delegate编程。文章列表: c#.net多线程同步.txt ...浅述WinForm多线程编程与Control.Invoke的应用.txt 微软.Net开发中的多线程编程总结.txt 线程中的参数传递.txt
VB.NET是一种基于.NET框架的编程语言,由微软公司开发,它是Visual Basic的现代版本,具有更强大的功能和更丰富的语法结构。VB.NET源代码是指使用VB.NET编写的程序或应用程序的原始文本,这些代码可以被编译器转换为...
4. **事件驱动编程**:VB.NET中的控件和窗体支持事件驱动编程,开发者可以为控件添加事件处理程序,如按钮的Click事件,文本框的TextChanged事件等。 5. **LINQ(Language Integrated Query)**:VB.NET支持语言...
VB.NET是一种基于.NET框架的编程语言,由微软公司开发,是Visual Basic的现代版本,具有更强大的功能和更丰富的库支持。在这个项目中,“VB.NET---计算器---源代码”是一个使用VB.NET编写的简单计算器应用程序。它...
VB.NET判断网络连接状态
VB.NET多线程编程技术是一种提高应用程序性能的关键手段,尤其对于时间密集型或处理密集型的任务,它能够显著提升程序响应速度和资源利用效率。在VB.NET中,多线程编程主要依赖于`.NET框架`中的`System.Threading`...
此外,VB.NET还支持XML处理、Web服务调用、多线程编程、反射以及与.NET Framework其他组件的集成,这些都是现代软件开发中不可或缺的部分。 总的来说,《VB.NET应用教程第2版》的数据包是学习VB.NET编程的宝贵资料...
使用VB.NET对PLC进行读写数据,方便快捷,对入门者有很好的编程
VB.NET是一种面向对象的编程语言,由微软公司开发,它与.NET框架紧密集成,提供了丰富的库和工具支持,使得开发Windows桌面应用、Web应用以及服务变得更为便捷。设计模式在VB.NET中的应用,可以极大地提高代码质量和...
VB.NET是一种基于.NET框架的编程语言,由微软公司开发,用于构建桌面应用、Web应用以及Windows服务等。这个“VB.net编程实例(101个)”集合为初学者提供了丰富的学习资源,涵盖了多个关键领域,包括Web开发、...
11. **多线程与并发**:VB.NET提供了Threading类库,用于处理多线程编程,以实现并行计算和优化性能。了解如何正确管理和同步线程是提高程序效率的关键。 这个高级教程涵盖了VB.NET的核心高级特性,通过深入学习,...
**VB.NET与VB编程方面的主要区别** VB.NET和Visual Basic(简称VB)是两种不同的编程环境,虽然它们在历史上有着紧密的联系,但随着时间的推移,两者之间的差异变得越来越明显。本文将深入探讨VB.NET与VB编程的主要...
VB.NET视频格式转换源代码 - 副本.zip
VB.Net to C# Converter(代码转换工具) v2.23 VB.Net to C Sharp Converter 是一款将vb.net代码转化为c#代码的程序。在转化过程中,保留了原有的注释和变量名。 VB.Net to C# Converter是一款代码转换软件,将用户...
在VB.NET编程环境中,多线程技术是一种提升应用程序性能的重要手段。它允许程序同时执行多个任务,从而提高程序的响应速度和效率。本实例主要关注如何在VB.NET中实现多线程,通过创建并运行三个具有类似功能的方法...
《VB.NET实例解析应用编程100例》是一本深入探讨VB.NET编程实践的书籍,旨在帮助开发者通过具体的实例学习和掌握VB.NET编程技术。这本书可能涵盖了从基础语法到高级特性的广泛主题,包括控件使用、数据访问、网络...
AUTOCAD VBA&VB.NET开发基础与实例教程 c#
【VB.Net 2010 与 VB6 的差异与转换】 VB.Net 2010 是 Microsoft .Net Framework 下的一个编程环境,相较于之前的 VB6(Visual Basic 6.0),它引入了许多新特性和改进,旨在提升开发效率和代码质量。VB6 是基于...
第一部分 Visual Basic.net基础 第二部分 vb.net的语法部分 第三部分 visual basic.net的运算 第四部分 visual basic.net的常用控件 第六部分 vb.net的OOP...第八部分 vb.net的多线程 第九部分 vb.net的文件和出错处理
vb.net2003编写的HID测试程序,根据网上的VB6修改,功能已经全部实现。包括HidD_GetHidGuid,SetupDiGetClassDevs,SetupDiEnumDeviceInterfaces,CreateFile,SetupDiGetDeviceInterfaceDetail等API函数的声明和...