知识卡片
本地方法调用的四个步骤在跨进程后为何全部失效
内容
一次本地方法调用要经过四步:把参数压栈传给被调用方(Callee)、根据方法签名 确定具体执行版本、从栈中取参数执行、把结果压栈并把指令流恢复到调用点继续 执行。这四步能顺利运作,前提是调用者(Caller)和被调用者共享同一块内存 地址空间和同一套语言规则。一旦Callee不在当前进程里,这两个前提同时崩塌: 第一,压栈传参依赖的是本进程的栈内存,把参数压在Caller进程的栈里对另一个 进程的执行毫无意义;第二,方法版本选择依赖语言规范,如果两个进程用不同 语言实现,”该调用哪个版本”就成了没有答案的模糊问题。这正是”远程调用”和 “本地调用”只差两个字、复杂度却天差地别的根源——不是概念上难以理解,而是 支撑本地调用高效运作的两个隐藏假设(共享内存、共享语言规则)在跨进程场景 下同时失效,必须用新的机制(进程间通信)重新解决”怎么把参数和结果搬过去” 这个问题。
参考来源
- 位置:《凤凰架构:构建可靠的大型分布式系统》第2章"访问远程服务"2.1.1节
"进程间通信"(源文件:_epub-src对应OEBPS/Text/chapter14.xhtml)
- 结论依据:原文用Java伪代码逐步拆解本地方法调用的四个步骤,再指出若Callee
不在同一进程,压栈传参依赖的栈内存不共享、方法版本选择依赖的语言规则不
通用,直接支撑"两个隐藏假设失效导致远程调用复杂度剧增"这一结论。
- 原始内容:如果Caller与Callee分属不同的进程,就不会拥有相同的栈内存,此时
将参数在Caller进程的内存中压栈,对于Callee进程的执行毫无意义……如果Caller
与Callee不是同一种语言实现的程序,方法版本选择就将是一项模糊的不可知行为。