spring启动后保证创建的对象不被垃圾回收器回收

一、可达性分析(根搜索)算法

JVM通过可达性分析来判定对象是否存活。这个算法的基本思路就是通过一系列称为GC Roots的对象作为起始点,从这些节点开始向下搜索,搜索所走过的路径称为引用链,当一个对象到GC Roots没有任何引用链相连时,则证明此对象是不可用的。如下图中对象object1object2object3object4是可用的对象,object5object6object7虽然互相关联,但是它们到GC Roots是不可达的,所以它们将会被判定为是可回收的对象。

在Java语言中,可作为GC Roots的对象包括下面几种:

1、虚拟机栈(栈帧中的本地变量)中引用的对象。

2、方法区中类静态属性引用的对象。

3、方法区中常量引用的对象。

4、本地方法栈中JNI(Native方法)引用的对象。

二、spring源代码

spring创建对象是通过实现接口BeanFactory的类来实现的,有如下的实现结构:

SimpleJndiBeanFactory.java

public class SimpleJndiBeanFactory extends JndiLocatorSupport implements BeanFactory {
  private final Set<String> shareableResources = new HashSet();
  //使用new创建的map,是栈中引用的对象,可作为GC Roots 对象
  private final Map<String, Object> singletonObjects = new HashMap();
  private final Map<String, Class<?>> resourceTypes = new HashMap();
  public SimpleJndiBeanFactory() {
    this.setResourceRef(true);
  }
  public void addShareableResource(String shareableResource) {
    this.shareableResources.add(shareableResource);
  }
  public void setShareableResources(String... shareableResources) {
    this.shareableResources.addAll(Arrays.asList(shareableResources));
  }
  public Object getBean(String name) throws BeansException {
    return this.getBean(name, Object.class);
  }
}

StaticListableBeanFactory.java

public class StaticListableBeanFactory implements ListableBeanFactory {
  private final Map<String, Object> beans;
  public StaticListableBeanFactory() {
    //使用new创建的map,是栈中引用的对象,可作为GC Roots 对象
    this.beans = new LinkedHashMap();
  }
  public StaticListableBeanFactory(Map<String, Object> beans) {
    Assert.notNull(beans, "Beans Map must not be null");
    this.beans = beans;
  }
  public void addBean(String name, Object bean) {
    this.beans.put(name, bean);
  }
}

从上面的源代码可以看出,对象存放在一个Map中,其中mapsingletonObjects是用来存放单例对象的。map singletonObjectsbeans(在构造方法中new)都是直接使用关键字new创建,是强引用,满足作为GC Roots对象的条件(虚拟机栈(栈帧中的本地变量)中引用的对象)。这样创建的对象存在map中和GC Roots对象相连,所以不会被回收。

总结

以上就是这篇文章的全部内容了,希望本文的内容对大家的学习或者工作能带来一定的帮助,如果有疑问大家可以留言交流。

(0)

相关推荐

  • 详解springmvc 接收json对象的两种方式

    最近学习了springmvc 接收json对象的两种方式,现在整理出来,具体如下: 1.以实体类方式接收 前端 ajax 提交数据: function fAddObj() { var obj = {}; obj['objname'] = "obj"; obj['pid'] = 1 ; $.ajax({ url: 'admin/Obj/addObj.do', method: 'post', contentType: 'application/json', // 这句不加出现415错误:U

  • 详解SpringMVC @RequestBody接收Json对象字符串

    页面提交请求参数有两种,一种是form格式提交,一种json格式提交 通常情况下我们使用的都是form格式提交的数据,数据格式:k=v&k=v,这个时候用springMVC接收参数没有问题,但有时候前端会通过json向后端传递数据,就会出现springMVC获取不到参数值的情况 注意:jQuery的$.post方法虽然也可以传递json格式数据,但实际上是用的form格式提交,jquery会帮你把json转成form格式提交后台 所以其实可以通过$.post,$.get来提交json格式,让jq

  • SpringMVC接收多个对象的4种方法

    问题背景: 我要在一个表单里同时一次性提交多名乘客的个人信息到SpringMVC,前端HTML和SpringMVC Controller里该如何处理? 第1种方法:表单提交,以字段数组接收: 第2种方法:表单提交,以BeanListModel接收: 第3种方法:将Json对象序列化成Json字符串提交,以List接收: 第4种方法:将表单对象序列化成Json字符串提交,以List接收: 第4种方法其实是第3种方法的升级,就是将表单转成Json对象,再转成Json字符串提交: 然而,第4种方法还不

  • jsp 显示springmvc modelmap传递的对象详细介绍

    jsp 显示springmvc modelmap传递的对象 最近在做一个小网站,功能非常基础,决定用springmvc搭建. 遇到一个问题,在controller向前端传值时,比如使用ModelMap传了一个字符串,modelmap.addattribute("msg", "hello"),那么在jsp端,直接使用${msg}就可以显示.接着,如果我传递了一个对象,依然可以使用${obj.name}这样的方法来显示该对象的各个属性.然而更多情况下,都需要显示列表,所

  • Java中对象的深复制(深克隆)和浅复制(浅克隆)介绍

    1.浅复制与深复制概念 ⑴浅复制(浅克隆) 被复制对象的所有变量都含有与原来的对象相同的值,而所有的对其他对象的引用仍然指向原来的对象.换言之,浅复制仅仅复制所考虑的对象,而不复制它所引用的对象. ⑵深复制(深克隆) 被复制对象的所有变量都含有与原来的对象相同的值,除去那些引用其他对象的变量.那些引用其他对象的变量将指向被复制过的新对象,而不再是原有的那些被引用的对象.换言之,深复制把要复制的对象所引用的对象都复制了一遍. 2.Java的clone()方法 ⑴clone方法将对象复制了一份并返回

  • Java的MyBatis+Spring框架中使用数据访问对象DAO模式的方法

    SqlSessionTemplate SqlSessionTemplate是MyBatis-Spring的核心.这个类负责管理MyBatis的SqlSession,调用MyBatis的SQL方法,翻译异常.SqlSessionTemplate是线程安全的,可以被多个DAO所共享使用. 当调用SQL方法时,包含从映射器getMapper()方法返回的方法,SqlSessionTemplate将会保证使用的SqlSession是和当前Spring的事务相关的.此外,它管理session的生命周期,包

  • Spring mvc 接收json对象

    本文通过代码实例介绍spring mvc 接收json数据的方法,具体详情如下所示: 接收JSON 使用 @RequestBody 注解前台只需要向 Controller 提交一段符合格式的 JSON,Spring 会自动将其拼装成 bean. 1)在上面的项目中使用第一种方式处理返回JSON的基础上,增加如下方法: Java代码 @RequestMapping(value="/add",method=RequestMethod.POST, headers = {"conte

  • JAVA对象JSON数据互相转换的四种常见情况

    1. 把java 对象列表转换为json对象数组,并转为字符串 复制代码 代码如下: JSONArray array = JSONArray.fromObject(userlist);     String jsonstr = array.toString(); 2.把java对象转换成json对象,并转化为字符串 复制代码 代码如下: JSONObject object = JSONObject.fromObject(invite);    String str=object.toString

  • Java的Spring框架中DAO数据访问对象的使用示例

    Spring DAO之JDBC   Spring提供的DAO(数据访问对象)支持主要的目的是便于以标准的方式使用不同的数据访问技术, 如JDBC,Hibernate或者JDO等.它不仅可以让你方便地在这些持久化技术间切换, 而且让你在编码的时候不用考虑处理各种技术中特定的异常. 为了便于以一种一致的方式使用各种数据访问技术,如JDBC.JDO和Hibernate, Spring提供了一套抽象DAO类供你扩展.这些抽象类提供了一些方法,通过它们你可以 获得与你当前使用的数据访问技术相关的数据源和其

  • JSP 获取Spring 注入对象示例

    <%@ page import="org.springframework.web.context.support.WebApplicationContextUtils"%> <%@ page import="org.springframework.context.ApplicationContext"%> ServletContext sc = this.getServletConfig().getServletContext(); Appl

随机推荐