Dav*_*one 4 c# java memory-management buffer-overflow
我正在阅读2010年CWE/SANS排名前25位最危险的编程错误,其中一个条目是缓冲区复制而不检查输入大小.它建议使用具有功能的语言来预防或缓解此问题,并说:
例如,许多执行自己的内存管理的语言(如Java和Perl)不会受到缓冲区溢出的影响.其他语言(如Ada和C#)通常提供溢出保护,但程序员可以禁用保护.
我不知道Java和C#在内存管理方面有任何有意义的不同.Java如何不受缓冲区溢出的影响,而C#只能防止溢出?如何在C#中禁用这种保护?
好的答案。我想补充一点,Java 取决于堆栈或堆内存位置的使用。C# 也是如此。使用原始指针的想法是对 C# 的补充,源自 C 代码背景。尽管 C# 和 C/C++ 不是同一种代码语言,但它们确实共享一些共性语义。使用“不安全”代码的想法可以让您避免在堆上保留大型对象,其中每个运行时实例的内存限制为 2GB 左右(对于每个 CLR 的 C#,每个 JVM 实例的 Java),而不会因垃圾收集而导致性能急剧下降。在某些情况下,您可以使用 C# 的能力来利用不安全或手动管理的内存指针来解决这样一个事实:没有那么多第三方工具可以解决堆外缓存等问题。
我要提醒您的是,如果您确实使用不安全的代码,请务必熟悉“一次性类型”和“终结器”。这可能是一种相当高级的实践,不正确处理对象的后果与 C 代码相同……可怕的内存泄漏。后果是你的应用程序内存不足并且它崩溃了(不好)。这就是为什么 C# 默认情况下不允许这样做,并且您需要使用“unsafe”关键字覆盖手动控制指针的任何使用。这确保了任何手动处理的内存都是有意的。处理“不安全”关键字时,请戴上 C 代码帽子。
Andrew Troelsen 的“Pro C# 2010 和 .Net Platform”中的“Understanding Object Lifetime”一章对此有很好的参考。如果您更喜欢在线参考,请参阅 MSDN 网站实现 Finalize 和 Dispose 以清理非托管资源
最后一点 - 非托管内存在对象的终结器部分中释放(~ObjectName(){...})。这些模式确实会增加性能开销,因此如果您正在处理较低延迟的场景,那么保持对象轻量可能是最好的选择。如果您正在处理人类反应,那么您应该在绝对必要时考虑这一点。
| 归档时间: |
|
| 查看次数: |
2835 次 |
| 最近记录: |