当你拥有一个应用服务器,并且想要在其中运行第三方插件时,你可以使用限制性安全管理器来阻止它们做诸如 System.exit() 等操作,但这只算是半个解决方案。这些不受信任的插件仍然可能进入无限循环或者在你来不及反应之前消耗所有的自由堆内存。Thread.stop() 已被弃用,所以你不能简单地杀死一个肆意妄为的线程,而由于堆是共享的,当插件使用完所有堆内存时,不仅插件会出现 OutOfMemoryError,所有其他正在运行的线程也将出现此问题。
是否有一些开源的应用程序/API/框架可以操纵插件类的字节码,使线程可停止和/或跟踪分配情况,以便如果线程分配过多则可以将其杀死?即使代码没有准备好“封装”以“单独使用”的形式,你也可以通过插入能够随意产生异常并由另一个“管理”线程触发的代码来使 Thread 可停止,并确保该异常未被插件捕获。并且你可以添加某种计数器来计算调用和循环次数以及分配量,并让“管理”线程杀死破坏了配置限制的插件。
我认为所有这些都可以通过 ASM 来完成,但我希望它们已经被做过了。我可以让插件在它们自己的 JVM 中运行,但这将涉及大量的数据编组/解组,并且如果插件 JVM 死亡/崩溃,我仍然不知道潜在的几十个(100?)插件中哪一个是问题所在,我不可能每个插件运行一个 JVM。我已经找到了一些相关的问题,但没有解决无限循环和消耗堆内存的问题:
是否有一些开源的应用程序/API/框架可以操纵插件类的字节码,使线程可停止和/或跟踪分配情况,以便如果线程分配过多则可以将其杀死?即使代码没有准备好“封装”以“单独使用”的形式,你也可以通过插入能够随意产生异常并由另一个“管理”线程触发的代码来使 Thread 可停止,并确保该异常未被插件捕获。并且你可以添加某种计数器来计算调用和循环次数以及分配量,并让“管理”线程杀死破坏了配置限制的插件。
我认为所有这些都可以通过 ASM 来完成,但我希望它们已经被做过了。我可以让插件在它们自己的 JVM 中运行,但这将涉及大量的数据编组/解组,并且如果插件 JVM 死亡/崩溃,我仍然不知道潜在的几十个(100?)插件中哪一个是问题所在,我不可能每个插件运行一个 JVM。我已经找到了一些相关的问题,但没有解决无限循环和消耗堆内存的问题: