将来,托管运行时是否会针对细微的数据损坏问题提供额外保护?
Java和.NET CLR等托管运行时减少或消除了C#等本机语言中常见的许多内存损坏错误的可能性。尽管如此,令人惊讶的是,它们不能免受所有内存损坏问题的影响。直观地期望一种验证其输入,没有错误并且鲁棒地处理异常的方法总是将其对象从一个有效状态转换为另一个有效状态,但事实并非如此。 (更准确地说,使用流行的编程约定不是这种情况 - 对象实现者需要尽力避免我描述的问题。)
请考虑以下情况:
线程。调用者可能与其他线程共享该对象并对其进行并发调用。如果对象未实现锁定,则字段可能已损坏。 (也许 - 除非通知对象是线程安全的 - 运行时应该在每个方法调用上使用一个互锁,如果同一对象上的任何方法在另一个线程上并发执行,则抛出异常。这将是一个保护功能,只是与其他广受欢迎的托管运行时安全功能一样,它有一些成本。)
重入。该方法对任意函数(例如事件处理程序)进行调用,该函数最终调用对象上的方法,这些方法不是为那时设计的。这比线程安全更棘手,许多类库都没有做到这一点。 (更糟糕的是,众所周知,类库很难记录允许重入的内容。)
对于所有这些情况,可以认为彻底的文档是一种解决方案。但是,文档还可以规定如何在非托管语言中分配和释放内存。我们从经验中知道(例如,通过内存分配),文档和语言/运行时执行之间的差异是白天和黑夜。
我们对未来的语言和运行时有什么期望可以保护我们免受这些问题和其他类似的细微问题的影响?
答案 0 :(得分:2)
我认为语言和运行时将继续向前发展,不断向开发人员提取问题,并使我们的生活更轻松,更高效。
举个例子 - 线程。 .NET世界中有一些很棒的新功能可以简化我们日常使用的线程模型。例如,STM.NET最终可能使共享状态变得更加安全。与当前技术相比,.NET 4中的parallel extensions使线程的生命变得非常容易。
答案 1 :(得分:1)
我认为交易记忆有望解决其中的一些问题。我不确定这是否能以某种方式回答你的问题,但无论如何这都是一个有趣的话题:
http://en.wikipedia.org/wiki/Software_transactional_memory
大约一年前,有一集关于这个主题的软件工程广播可能。
答案 2 :(得分:1)
首先,“托管”有点用词不当:像OCaml,Haskell和SML这样的语言在完全编译时实现了这样的保护和安全性。所有相关的“管理”都是在编译时通过静态分析发生的,这有助于优化和加速。
无论如何,要回答你的问题:如果你看一下像Erlang和Haskell这样的语言,默认情况下状态是孤立的和不可变的。对于某种类型的系统,线程和重入是默认安全的,并且因为你必须不遗余力地打破这些规则,所以很明显可以看到不安全代码的出现位置。
从安全默认值开始,但为高级不安全使用留出空间,您可以获得两全其美的效果。根据您的定义,未来的安全系统也可能遵循其中的一些做法,这似乎是合理的。
答案 3 :(得分:0)
我们将来可以期待什么?
无。线程状态和重新入侵不是我看到工具/运行时解决的问题。相反,我认为将来人们会转向避免使用可变状态进行编程的样式来绕过这些问题。语言和库可以帮助使这些编程风格更具吸引力,但工具不是解决方案 - 改变我们编写代码的方式就是解决方案。