垃圾收集会导致糟糕的软件设计吗?

Does garbage collection lead to bad software design?

我听说垃圾收集会导致糟糕的软件设计。真的吗?的确,我们不关心垃圾收集语言中对象的生命周期,但这对程序设计有影响吗?

如果一个对象要求其他对象代表它做某事,直到另行通知,该对象的所有者应该在不需要它的服务时通知它。让代码放弃这些对象而不通知它们不再需要它们的服务将是糟糕的设计,但在垃圾收集框架和非 GC 框架中都是如此。

垃圾收集框架如果使用得当,有两个好处:

  1. 在许多情况下,创建对象的目的是为了在其中封装值,并且对对象的引用作为该数据的代理传递。接收此类引用的代码不应该关心是否存在对这些相同对象的其他引用,或者它是否包含最后一个幸存的引用。只要有人持有对对象的引用,就应该保留数据。一旦没有人需要这些数据,它就应该不复存在,但应该没有人特别注意。

  2. 在非 GC 框架中,尝试使用已处置的对象通常会生成无法可靠捕获的未定义行为(并且可能允许代码违反安全策略)。在许多 GC 框架中,可以确保使用已处置资源的尝试将被确定性地捕获并且不会破坏安全性。

在某些情况下,垃圾收集将允许程序员 "get away with" 比非 GC 系统中可以容忍的设计更草率。然而,基于 GC 的框架也将允许使用许多在非 GC 系统中无法有效实现的良好编程模式。例如,如果一个程序使用多个工作线程来寻找问题的最佳解决方案,并且有一个 UI 线程定期想要显示目前找到的最佳解决方案,那么 UI 线程会想要知道当它请求状态更新时,它会得到 a 已找到的解决方案,但不想让工作线程负担必要的同步以确保它具有绝对-最新解决方案。

在非 GC 系统中,线程同步是不可避免的,因为 UI 线程和工作线程必须协调谁将删除一个在显示时变得过时的状态对象。然而,在基于 GC 的系统中,GC 将能够判断 UI 线程是否能够在状态对象被替换之前获取对状态对象的引用,从而确定该对象是否需要保持活动状态足以让 UI 线程显示它。 GC 有时必须强制线程同步以找到所有可访问的引用,但与非 GC 系统中所需的频繁线程同步相比,GC 的偶尔同步可能会造成更少的性能损失。