问题描述
但是我不明白为什么要这么做,因为为什么Java垃圾回收框架不会自动释放内存? 我知道一个对象如果有引用就不会被垃圾回收。 让我们举个例子:
public class MyServiceImpl{
@Reference
ResourceResolverFactory rrf;
public void someFunction(){
ResourceResolver resourceResolver = rrf.getServiceResourceResolver(Map object);
resourceResolver.getResource(path);
}
}
在上面的代码中,resourceResolver对象用于仅获取资源。并且在函数执行结束之后,不再存在针对resourceResolver对象的引用。所以我不明白为什么Java垃圾收集器无法释放内存?它仍然拥有什么参考?
我能想到的一个原因是,我知道ResourceResolverFactory类提供了Singleton对象,并且在Singleton类的情况下,该对象直到程序结束才有资格进行垃圾回收,并且在此期间,如果我们创建了数千个ResourceResolver对象,则将内存在程序结束之前不会释放。这是正当的理由吗? Singleton ResourceResolverFactory和ResourceResolver对象之间是否有任何内存映射?
解决方法
ResourceResolver
接口抽象出了跨多个源访问资源的细节。根据底层实现,这可以是JCR,捆绑资源或其他某种形式的存储。访问基础“数据库”可能需要某种形式的身份验证。例如,通常,当从AEM中的存储库中读取资源时,每个资源解析器都会打开一个底层的JCR会话。不再需要该会话时,需要终止该会话。广义上讲,它不仅仅是纯粹的垃圾回收/内存管理约束,而且取决于基础实现,还可能涉及其他一些资源清除。 ResourceProvider
上的Javadoc对此进行了更详细的说明。
也就是说,这种行为是通过许多接口及其相应的实现类实现的,这些接口引入了一些有趣的东西,与垃圾回收过程有关。
CommonResourceResolverFactoryImpl
类实现了所有资源解析器工厂的共享功能(请参阅ResourceResolverFactory
),是一个holds a map of weak references打开ResourceResolver
实例的单例。
由于特定的ResourceResolver
实例已关闭,因此必须为cleaned up。
您可能会注意到有一个ResourceResolverControl
associated with each of those ResourceResolver
instances。 ResourceResolverControl
类可确保所有ResourceProvider
实例与周围的ResourceResolver
一起正确关闭。当您关闭特定的ResourceResolver
时,它就是orchestrated by the relevant ResourceResolverFactory
我的理解方式,这些类之间的关系及其垃圾回收的含义不是原因,我们必须称之为ResourceResolver#close
。该设计反映了有必要抽象出不同的提供程序,其中一些使用资源进行清理。