2

将来,托管运行时是否会针对细微的数据损坏问题提供额外的保护?

Java 和 .NET CLR 等托管运行时减少或消除了 C# 等本地语言中常见的许多内存损坏错误的可能性。尽管如此,令人惊讶的是,它们并不能免受所有内存损坏问题的影响。人们直观地期望验证其输入、没有错误并稳健地处理异常的方法将始终将其对象从一种有效状态转换为另一种有效状态,但事实并非如此。(更准确地说,使用流行的编程约定并非如此——对象实现者需要竭尽全力避免我描述的问题。)

考虑以下场景:

  1. 穿线。调用者可能与其他线程共享对象并对其进行并发调用。如果对象未实现锁定,则字段可能已损坏。(也许——除非通知对象是线程安全的——如果同一对象上的任何方法在另一个线程上同时执行,运行时应该在每个方法调用上使用互锁以引发异常。这将是一种保护功能,只是与托管运行时的其他广为接受的安全功能一样,它也有一定的成本。)

  2. 重入。该方法对任意函数(例如事件处理程序)进行调用,该函数最终调用对象上的方法,而这些方法并非设计为在该点调用。这甚至比线程安全更棘手,许多类库都没有做到这一点。(更糟糕的是,众所周知,类库很少记录允许重入的内容。)

对于所有这些情况,可以说完整的文档是一种解决方案。但是,文档也可以规定如何在非托管语言中分配和取消分配内存。我们从经验中知道(例如,内存分配),文档和语言/运行时执行之间的区别是白天和黑夜。

我们对未来的语言和运行时有什么期望来保护我们免受这些问题和其他类似的微妙问题的影响?

4

4 回答 4

2

我认为语言和运行时将不断向前发展,不断从开发人员那里抽象出问题,并不断让我们的生活更轻松、更高效。

以你的例子 - 线程。.NET 世界中即将出现一些很棒的新功能,以简化我们日常使用的线程模型。 例如, STM.NET最终可能会使共享状态的处理更加安全。与当前技术相比,.NET 4 中的并行扩展使线程化变得非常容易。

于 2009-10-16T23:07:03.027 回答
1

我认为事务性内存有望解决其中一些问题。我不确定这是否以某种方式回答了您的问题,但无论如何这是一个有趣的话题:

http://en.wikipedia.org/wiki/Software_transactional_memory

大约一年前,软件工程电台有一个关于这个话题的插曲。

于 2009-10-16T23:10:41.730 回答
1

首先,“托管”有点用词不当:像 OCaml、Haskell 和 SML 这样的语言在完全编译的同时实现了这样的保护和安全。所有相关的“管理”都通过静态分析在编译时发生,这有助于优化和速度。

无论如何,回答你的问题:如果你看看像 Erlang 和 Haskell 这样的语言,默认情况下状态是孤立的和不可变的。对于某种系统,线程和重入默认情况下是安全的,并且因为您必须竭尽全力打破这些规则,所以很明显可以看到不安全代码可能出现的位置。

从安全的默认设置开始,但为高级的不安全使用留出空间,您可以两全其美。根据您的定义,未来安全的系统也可能遵循其中一些做法,这似乎是合理的。

于 2009-10-18T01:09:43.180 回答
0

未来我们可以期待什么?

没有。线程状态和重入不是我看到工具/运行时解决的问题。相反,我认为未来人们将转向避免使用可变状态进行编程以绕过这些问题的风格。语言和库可以帮助使这些编程风格更具吸引力,但工具并不是解决方案——改变我们编写代码的方式才是解决方案。

于 2009-10-16T23:08:42.043 回答