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

标签 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 的增长。

当然,我可以在每次需要时重新启动我的生产服务器
重新部署我的应用程序,但我想找出问题所在。


PS:数据源实现:

@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;
    }
}

最佳答案

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

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

因此,PermGen 问题出在其他地方。这一直是 tomcat 的一个众所周知的问题,但他们声称这是泄漏的应用程序代码。这基本上是正确的,但很难追踪尚未注册的内容。 Tomcat 尝试清除 PermGen 问题的常见原因,但无法涵盖所有​​内容。

关于java - Spring jdbc模板内存泄漏在非常基本的应用程序中,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/7498063/

相关文章:

java - 解密错误: "no iv set when one expected"

java - JSR 303 - Hibernate Validation 4.2.0 - UnexpectedTypeException - @Valid 和@Size 组合

java - 在android上通过java中的http post分块上传文件

java - OAuth2RestTemplate 身份验证问题获取 access_denied

java - MySQL 服务器 5.1.72 的正确 JDBC 版本是什么?

java - 使用 maven- assembly-plugin 包含所需的驱动程序时找不到合适的驱动程序

java - 报错Sqoop mysql驱动加载异常

java - 当我尝试解析 XML 时出错

spring - 如何使用 Spring 框架从属性文件中获取值到 Map 中?

java - Spring:通过构造函数注入(inject)静态成员(System.in)