Java 在Spring应用程序中创建和销毁原型bean期间,跟踪内存状况的一种方法?

Java 在Spring应用程序中创建和销毁原型bean期间,跟踪内存状况的一种方法?,java,spring,memory-management,prototype,javabeans,Java,Spring,Memory Management,Prototype,Javabeans,在我们项目的一部分中,我们有一些原型bean。我想清楚地了解在执行该部分的过程中发生了什么 在创建原型bean的过程中,是否有任何方法来跟踪情况、它们开始使用的内存量,以及跟踪这些bean是否被成功销毁 我不仅需要在控制台中打印信息,还希望查看内存的实际情况或内存中现有原型bean的列表。任何标准探查器都会帮助您收集所需的数据。要快速而肮脏地看一眼: 但是,我可以帮助解释原型的生命周期,这可能会澄清您的一些问题 在大多数软件解决方案中,您都有管理对象,这些对象通常是作为单例实现的,并且您通常根据

在我们项目的一部分中,我们有一些原型bean。我想清楚地了解在执行该部分的过程中发生了什么

在创建原型bean的过程中,是否有任何方法来跟踪情况、它们开始使用的内存量,以及跟踪这些bean是否被成功销毁


我不仅需要在控制台中打印信息,还希望查看内存的实际情况或内存中现有原型bean的列表。

任何标准探查器都会帮助您收集所需的数据。要快速而肮脏地看一眼:

但是,我可以帮助解释原型的生命周期,这可能会澄清您的一些问题

在大多数软件解决方案中,您都有管理对象,这些对象通常是作为单例实现的,并且您通常根据需要实例化数据对象

在spring中,创建的所有bean都标记为单例,并由spring进行内部管理

当您创建一个原型bean时,spring只返回该bean的一个新实例,但是它管理该bean的依赖注入

因此:

当您需要原型中的重要字符串时:

@Scope("prototype")
public class MyPrototypeBean{
    @Bean("importantString")
    private String myString;

    public String getString(){
      return importantString;
    }
}
Spring将缓存重要字符串,但您的应用程序现在将负责处理原型生命周期,就像处理任何新的MyObject()一样


我希望这有帮助

任何标准探查器都会帮助您收集所需的数据。要快速而肮脏地看一眼:

但是,我可以帮助解释原型的生命周期,这可能会澄清您的一些问题

在大多数软件解决方案中,您都有管理对象,这些对象通常是作为单例实现的,并且您通常根据需要实例化数据对象

在spring中,创建的所有bean都标记为单例,并由spring进行内部管理

当您创建一个原型bean时,spring只返回该bean的一个新实例,但是它管理该bean的依赖注入

因此:

当您需要原型中的重要字符串时:

@Scope("prototype")
public class MyPrototypeBean{
    @Bean("importantString")
    private String myString;

    public String getString(){
      return importantString;
    }
}
Spring将缓存重要字符串,但您的应用程序现在将负责处理原型生命周期,就像处理任何新的MyObject()一样


我希望这有帮助

如果需要以编程方式进行,请尝试使用此

此类提供所需的服务 插入Java编程语言代码。仪器是最重要的 将字节码添加到方法中,以便将数据收集到 被工具所利用。由于这些变化纯粹是累加性的,因此 工具不会修改应用程序状态或行为。这方面的例子 良性工具包括监视代理、探查器、覆盖率分析器、, 和事件记录器。有两种方法可以获取 仪表接口:

以指示代理类的方式启动JVM时。因为 一个插装实例被传递给的premain方法的情况 代理类

当JVM提供一种机制在JVM之后的某个时间启动代理时 发射。在这种情况下,将向 代理代码的agentmain方法

例如:


如果您需要以编程方式执行,请尝试使用以下方法

此类提供所需的服务 插入Java编程语言代码。仪器是最重要的 将字节码添加到方法中,以便将数据收集到 被工具所利用。由于这些变化纯粹是累加性的,因此 工具不会修改应用程序状态或行为。这方面的例子 良性工具包括监视代理、探查器、覆盖率分析器、, 和事件记录器。有两种方法可以获取 仪表接口:

以指示代理类的方式启动JVM时。因为 一个插装实例被传递给的premain方法的情况 代理类

当JVM提供一种机制在JVM之后的某个时间启动代理时 发射。在这种情况下,将向 代理代码的agentmain方法

例如:


我找到了一种方法查看创建的原型bean的实际图片。 我使用免费的VisualVM内存分析器

Sampler选项卡中,您可以看到创建的类的所有实例,包括单例bean和原型bean

您将看到自己的包和类的名称。在这种情况下:

  • prototype是一个包含我的原型bean的包

  • singleton是一个包含我的singleton bean的包

  • newclasses是一个包含由new操作符创建的类的包

同样在垃圾收集器将清理内存后,您将在此处看到结果


我找到了一种方法,可以查看创建的原型bean的实际图片。 我使用免费的VisualVM内存分析器

Sampler选项卡中,您可以看到创建的类的所有实例,包括单例bean和原型bean

您将看到自己的包和类的名称。在这种情况下:

  • prototype是一个包含我的原型bean的包

  • singleton是一个包含我的singleton bean的包

  • newclasses是一个包含由new操作符创建的类的包

同样在垃圾收集器将清理内存后,您将在此处看到结果


谢谢。实际上,我对单例和原型bean的生命周期有一些了解。我的问题是怎么做
public static void main(String[] args){

    MyProtoTypeBean myPrototypeBean = context.getBean(MyPrototypeBean.class);

    MyProtoTypeBean myPrototypeBean2 = context.getBean(MyPrototypeBean.class);

   String importantString = myPrototypeBean.getString();

   // each prototoype is reconstructed
   assert myProtoTypeBean != myPrototypeBean2;       

   myPrototypeBean = null;
   myPrototypeBean2 = null;

  // Since we are now handling the lifecycle of the prototype beans, as soon 
  //as we clear them and set them to null garbage collection will clear the 
  //prototype beans but not the importantString singleton
  //however spring will still have reference to the singleton string

  assert importantString == context.getBean("importantString");
}
public class MyAgent {
  private static volatile Instrumentation globalInstr;
  public static void premain(String args, Instrumentation inst) {
    globalInstr = inst;
  }
  public static long getObjectSize(Object obj) {
    if (globalInstr == null)
      throw new IllegalStateException("Agent not initted");
    return globalInstr.getObjectSize(obj);
  }
}