У меня есть приложение Spring mvc и Tomcat 7.0.21 в качестве контейнера сервлета.
И когда я пытаюсь использовать 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;
}
}