Spring jdbc模板内存泄漏在非常基本的应用程序中

时间:2011-09-21 10:10:05

标签: java spring jdbc memory-leaks

我有spring mvc应用程序和Tomcat 7.0.21作为servlet容器 当我在我的应用程序中尝试使用jdbcTemplate时,它无法正确重新部署 -
它可以防止jvm清理PermGen内存 坏代码的简单示例如下 (当然为了简单起见打破mvc概念):

@Controller
class MainController {
    private JdbcTemplate jdbcTemplate;
    @Autowired
    public void setDataSource(DataSource  dataSource) {
        this.jdbcTemplate = new JdbcTemplate(dataSource);
    }
    @RequestMapping("/")
    public String mainPage() {  
        jdbcTemplate.queryForObject("SELECT val FROM tbl WHERE id=1",
            String.class);
        return "main";
    }
}

没有jdbcTemplate.queryForObject(...)它完美无缺,但是 在部署到tomcat时,它会说:

Sep 21, 2011 1:54:38 PM org.apache.catalina.loader.WebappClassLoader clearReferencesJdbc
SEVERE: The web application [/my] registered the JDBC driver [com.mysql.jdbc.Driver] but failed to unregister it when the web application was stopped. To prevent a memory leak, the JDBC Driver has been forcibly unregistered.
Sep 21, 2011 1:54:38 PM org.apache.catalina.loader.WebappClassLoader clearReferencesThreads
SEVERE: The web application [/my] appears to have started a thread named [Timer-0] but has failed to stop it. This is very likely to create a memory leak.

之后我可以在VisualVM中看到每次重新部署应用程序时PermGen的增长。

当然,每次我想要时,我都可以重启我的生产服务器 重新部署我的应用程序,但我想弄明白什么是错误的。


P.S。:数据源实施:

@Configuration
public class ApplicationConfig {
    @Bean
    DataSource dataSource(@Value("${jdbc.driver}") String driver, 
        @Value("${jdbc.url}") String url, @Value("${jdbc.user}") String user,
        @Value("${jdbc.password}") String password) {

        BasicDataSource ds = new BasicDataSource();
        ds.setDriverClassName(driver);
        ds.setUrl(url);
        ds.setUsername(user);
        ds.setPassword(password);
        return ds;
    }
}

2 个答案:

答案 0 :(得分:2)

数据源应该为您处理取消注册JDBC驱动程序。见this related question。因此,请检查数据源实现的较新版本。 BasicDataSource不是数据源的最佳选择。尝试使用c3p0并查看是否重现了问题。

即使不是,Tomcat也会为你清除。顺便说一句,升级你的tomcat - 它在最新版本中对DriverManager泄漏有所改进。

因此,PermGen问题存在于其他地方。对于tomcat来说,这是一个众所周知的问题,但他们声称它是泄漏的应用程序代码。这基本上是正确的,但很难跟踪未注册的内容。 Tomcat尝试清除PermGen问题的常见原因,但不能涵盖所有内容。

答案 1 :(得分:1)

我不认为这是由于JDBCTemplate - 它是由驱动程序引起的。即使您执行DataSource.getConnection,您也应该看到相同的结果。