是否可以在运行时使用可执行内存堆和分布式系统进行修补程序?

Is it possible to have a hotfix at runtime with executable memory heaps and a distributed system?

我一直在查看一些有关 JIT 和在运行时分配可执行内存堆的教程。这主要是一个概念性的问题,如有不妥请指正。

如果我理解正确,JIT 利用运行时 interpreter/compiler 输出本机或可执行代码,如果是本机二进制文件,则将其放置在内存中的可执行代码堆中,即 OS-特定的(例如 Windows 的 VirtualAlloc(),Linux 的 mmap())。

此外,像 Erlang 这样的一些语言可以有一个分布式系统,这样每个部分都相互分离,这意味着如果一个失败,其他可以以模块化的方式解决这种情况,这意味着模块也可以如果管理得当而不影响整体执行,可以随意切换。

使用运行时编译器或某种代码交付机制,是否可以在运行时任意加载代码以替换可更新的代码模块?

例子

假设我有一个在 T 或 T 上运行的 sort(T, T) 函数。现在,假设我有一个在运行时加载的 merge_sort(T,T) 函数。如果我实施一种分类帐或登记系统,以便第一个 sort(T,T) 的用户可以重新分配自己使用新的 merge_sort(T,T) 功能并检测所有用户何时调整自己,那么我应该能够解除分配并从内存中删除 sort(T,T)

这基本上听起来很像 JIT,但对我来说,吸引人的部分是您可以在运行时任意交换模块代码的方面。那样的话,虽然系统没有满载,每个模块都被使用,模块可以自动切换到新代码,如果需要,等等。从理论上讲,这不是一种实现补丁的方法吗如果程序可以在各个模块中静默地换出代码,那么使用该程序的用户永远不必“重新启动”该程序?我想更大的分布式系统可以利用它,但是更小的系统呢?

Additionally, some languages like Erlang can have a distributed system such that each part is separated from each other, meaning that if one fails, the others can account for such a case in a modular way, meaning that modules can also be switched in and out at will if managed correctly without disturbing overall execution.

您正在描述如何制作一个 fault-tolerant 系统,该系统与替换 run-time 中的代码(在 Dynamic Software Update 或 DSU 中已知)完全不同。事实上,在 Erlang 中,您可以让一个进程监视其他进程,如果一个进程失败,它将把工作迁移到另一个进程以保持系统 运行 符合预期。请注意,DSU 不用于实现 fault-tolerance。它们是具有不同用途的不同功能。

Say I have a sort(T, T) function that operates on T or T. Now, suppose I have a merge_sort(T,T) function that I have loaded at runtime. If I implement a sort of ledger or register system such that users of the first sort(T,T) can reassign themselves to use the new merge_sort(T,T) function and detect when all users have adjusted themselves, I should then be able to deallocate and delete sort(T,T) from memory.

这称为 DSU,用于执行以下任何任务而无需关闭系统:

  • 修复一段代码中的一个或多个错误。
  • 修补安全漏洞。
  • 使用更高效的代码。
  • 部署新功能。

因此,任何应用程序或系统都可以使用 DSU,这样它就可以执行这些任务而无需重新启动。

Erlang 使您能够执行 DSU in addition to facilitating fault-tolerance as discussed above. For more information, refer to this Erlang write paper

实施 DSU 的方法有很多种。由于您对 JIT 编译器感兴趣并假设 "JIT compiler" 是指不仅编译 IL 代码而且分配可执行内存并使用二进制代码地址修补函数调用的组件,我将讨论如何在中实现 DSU JIT 环境。 JIT 编译器必须支持以下两个功能:

  • 在 run-time 获得或创建新二进制代码的能力。如果您有 IL 代码,则无需分配可执行内存,因为它必须被编译。
  • 能够用新代码替换一段 IL 代码(可能已经进行了 JIT)或二进制代码。

显然,有了这两个功能,您就可以在单个函数上执行 DSU。交换整个模块或库需要交换该模块导出的所有函数和全局变量。