【问题标题】:Sandbox for memory内存沙箱
【发布时间】:2015-07-25 11:45:09
【问题描述】:

Java 不应该有内存泄漏,但它仍然是可能的。当我的程序有内存泄漏时,我可以修复它(我希望)。但是当一些第三方包有它时,我该怎么办?除了不使用这个包之外几乎什么都没有。

还有其他解决方案吗?我喜欢沙盒的想法。您可以在某个区域内做任何您想做的事情,并且您的“身体”没有能力打扰您盒子之外的其他人。有没有办法在 Java 中为内存使用创建这样的沙箱?想象一下 = 为内存使用创建沙箱,允许一些包做它做的任何事情,获取结果并删除这个沙箱以及这里留下的任何垃圾! GC 没有并发症,没有清理或处置内存。只需删除并忘记它。

有办法吗?

【问题讨论】:

    标签: java memory memory-leaks


    【解决方案1】:

    最好的方法是启动另一个 JVM,通过 socket 与它通信(例如),并在完成后终止 JVM。

    讨论我们是否可以在同一个 JVM 中对其进行沙箱处理会很有趣。

    在您使用完 3rd 方库之后,您不再引用该库中的任何对象,那么仍然存在的垃圾可能是什么?

    1. 它们的类 - 即使您没有引用它们中的任何一个,如果它们由与您的代码相同的类加载器加载,这些类将持续存在。并且它们的静态字段可以引用更多的延迟数据,等等

    2. ThreadLocal - 它可能设置了一些线程局部变量,但没有清理它们

    3. 线程 - 它可能产生了一些持续存在的线程

    4. 在一些全球性的地方 - 例如。 System.setProperty() - 它会留在那里。

    所以总的来说,这可能很困难。

    但是,我们可以使用单独的类加载器和单独的线程来执行 3rd 方库,并且这种策略在大多数情况下可能会卸载所有 3rd 方创建的垃圾。

    是否有现有的工具可以做到这一点?我对此不太了解。我确实有一些实现热重载服务器的经验,并且我有一些可用于此目的的实用程序类。例如

    // wrap 3rd party code, expose it as some java.*.* interface
    public class MyWrapper implements Callable<String>
    {
        @Override 
        public String call()
        {
            return ThirdParty.query(..);
        }
    }
    
    
    
    HotReloader hot = new HotReloader();
    Callable<String> func = (Callable<String>)hot.getAppInstance("pkg.MyWrapper");
    String result = func.call();
    // then dereference `hot` and `func`
    

    HotReloader

    【讨论】:

    • 这是个好主意,但有点贵。你能想象为每个数据库请求启动新的 JVM 吗?我曾经参加过关于 Plumbr “我打赌你有内存泄漏”的 JavaOne 会议,他们的几个例子是关于标准数据库驱动程序中的内存泄漏的。如果我没记错的话是MySql。
    • 您可以使用 ClassLoaders 来隔离问题类。然后要清理库使用的任何内存,您只需删除对其类和加载器的所有引用。您还可以使用单独的 ThreadGroup 来隔离库线程,让您轻松杀死它们。
    • @IzoldTytykalo - 您可以使用一个 JVM 处理 2 个数据库请求 :) 或更多。
    • @Smith_61 - 是的,这可能在大多数情况下都有效。但这不是 100% 的证明。
    • @bayou.io 确实如此。在我能想到的大多数情况下都可以使用,但在不知道库类型的情况下很难找到完美的解决方案。
    猜你喜欢
    • 2013-05-17
    • 2017-06-24
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2018-05-28
    • 2015-03-05
    • 1970-01-01
    相关资源
    最近更新 更多