为什么应关闭resourceResolver对象

问题描述

here所述,我应该关闭从工厂获得的资源解析器。

一旦不再使用资源解析器以确保正确清理所有系统资源,则调用close()方法非常重要。

但是我不明白为什么要这么做,因为为什么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 instancesResourceResolverControl类可确保所有ResourceProvider实例与周围的ResourceResolver一起正确关闭。当您关闭特定的ResourceResolver时,它就是orchestrated by the relevant ResourceResolverFactory

我的理解方式,这些类之间的关系及其垃圾回收的含义不是原因,我们必须称之为ResourceResolver#close。该设计反映了有必要抽象出不同的提供程序,其中一些使用资源进行清理。