gpt4 book ai didi

java - cglib - MethodInterceptor & 完成?

转载 作者:搜寻专家 更新时间:2023-11-01 02:32:11 25 4
gpt4 key购买 nike

我使用 cglib MethodInterceptor 来包装服务。在对服务的每次调用中,它应该打开数据 session ,将调用传递给服务并最终关闭 session 。

但是,我注意到它在从 Finalizer 调用时行为不正常。我得到以下堆栈跟踪:

java.lang.IllegalArgumentException: interface my.pkg.SomeInterface is not visible from class loader
at java.lang.reflect.Proxy.getProxyClass(Proxy.java:353)
at java.lang.reflect.Proxy.newProxyInstance(Proxy.java:581)
at my.pkg.ProxyFactory.create(ProxyFactory.java:68)
at my.pkg.SomeService.make(SomeService.java:181)
at my.pkg.SomeService$SessionWrappingInterceptor.intercept(SomeService.java:1275)
at my.pkg.SomeService$$EnhancerByCGLIB$$b58faf6a.finalize(<generated>)
at java.lang.ref.Finalizer.invokeFinalizeMethod(Native Method)
at java.lang.ref.Finalizer.runFinalizer(Finalizer.java:83)
at java.lang.ref.Finalizer.access$100(Finalizer.java:14)
at java.lang.ref.Finalizer$FinalizerThread.run(Finalizer.java:160)

我做错了什么?我该如何解决?

最佳答案

当终结器最终选择您的对象(或您的 CGLIB 代理对象)进行终结时,垃圾收集器已确定您的对象无法访问并且即将被丢弃/收集。让我们假设这不是唯一被收集的对象,事实上它过去可能使用过的其他对象(包括它们的类加载器)也已被收集。

你的问题中没有足够的信息来确定发生了什么,但我的一般猜测是你的 ProxyFactory 正在做的工作需要这个类加载器曾经可以访问但不再可以访问的类,可能是由于事实上,您正处于垃圾收集的最后阶段。

我已经了解到处理 finalize() 调用的代理是非常危险的。在大多数情况下,您的代理目标确实不需要处理该调用,但如果需要,请不要在您的代理处理程序中执行任何创建、初始化或以其他方式创建对代理目标的引用的操作。 (例如,我的案例是一个按需加载的对象。当调用 finalize() 时,如果之前没有加载该对象,它将加载它并将值缓存在创建新的强引用链的某个地方,从而不允许代理类、它的类加载器和它引用的许多其他类被收集。大量内存泄漏。)

我的建议(虽然晚了)是禁止您的代理处理 finalize()。可以为 CGLIB 的增强器提供 CallbackFilters 以指示不要对 finalize() 方法执行任何操作,或者如果您使用的是简单的 MethodInterceptor,您可以自己检查一下。

最后一条评论:小心 CallbackFilter秒。它们也可能导致内存泄漏,尤其是当它们来自与 CGLIB 不同的类加载器时!您最终会得到 CGLIB 生成的对象,这些对象保留在不会被垃圾收集的 CallbackFilter 实例上。

关于java - cglib - MethodInterceptor & 完成?,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/6517348/

25 4 0
Copyright 2021 - 2024 cfsdn All Rights Reserved 蜀ICP备2022000587号
广告合作:1813099741@qq.com 6ren.com