【发布时间】:2017-12-16 17:32:10
【问题描述】:
我在停止/重新部署应用程序时遇到了 tomcat 内存泄漏问题。它说 以下 Web 应用程序已停止(重新加载、取消部署),但它们的 以前运行的类仍然加载到内存中,从而导致内存 泄漏(使用分析器确认):/test-1.0-SNAPSHOT
位于 Tomcat/lib 文件夹中的 MySQL 连接器驱动程序。 我可以在两者中重现此问题:Tomcat 7/8。还尝试了带有“net.sourceforge.jtds.*”驱动程序的 MS SQL 数据库,但没有帮助。
请在下面找到项目文件。项目仅在 DB 中创建 1 个表。
build.gradle
group 'com.test'
version '1.0-SNAPSHOT'
apply plugin: 'java'
apply plugin: 'war'
sourceCompatibility = 1.8
repositories {
mavenCentral()
}
dependencies {
compile group: 'org.hibernate', name: 'hibernate-entitymanager', version: '5.2.10.Final'
compile group: 'org.springframework.data', name: 'spring-data-jpa', version: '1.11.4.RELEASE'
compile group: 'org.springframework', name: 'spring-webmvc', version: '4.3.9.RELEASE'
providedCompile 'javax.servlet:javax.servlet-api:3.1.0'
providedCompile group: 'mysql', name: 'mysql-connector-java', version: '5.1.6'
compile group: 'commons-dbcp', name: 'commons-dbcp', version: '1.4'
}
ApplicationConfig.java
@Configuration
@Import({JPAConfiguration.class})
@EnableWebMvc
public class ApplicationConfig {}
JPAConfiguration.java
@Configuration
@EnableJpaRepositories("com.test.dao")
@EnableTransactionManagement
public class JPAConfiguration {
@Bean
public EntityManagerFactory entityManagerFactory() {
LocalContainerEntityManagerFactoryBean factory = new LocalContainerEntityManagerFactoryBean();
factory.setJpaVendorAdapter(new HibernateJpaVendorAdapter());
factory.setPackagesToScan("com.test.model");
factory.setDataSource(restDataSource());
factory.setJpaPropertyMap(getPropertyMap());
factory.afterPropertiesSet();
return factory.getObject();
}
@Bean(destroyMethod = "close")
public DataSource restDataSource() {
BasicDataSource dataSource = new BasicDataSource();
dataSource.setDriverClassName("com.mysql.jdbc.Driver");
dataSource.setUrl("jdbc:mysql://localhost:3306/test");
dataSource.setUsername("test");
dataSource.setPassword("test");
return dataSource;
}
private Map<String, String> getPropertyMap() {
Map<String, String> hibernateProperties = new HashMap<>();
hibernateProperties.put("hibernate.hbm2ddl.auto", "update");
hibernateProperties.put("hibernate.show_sql", "true");
hibernateProperties.put("hibernate.format_sql", "true");
hibernateProperties.put("hibernate.dialect", "org.hibernate.dialect.MySQL5InnoDBDialect");
return hibernateProperties;
}
@Bean
public PlatformTransactionManager transactionManager() {
JpaTransactionManager txManager = new JpaTransactionManager();
txManager.setEntityManagerFactory(entityManagerFactory());
return txManager;
}
}
TestRepository.java
@Repository
public interface TestRepository extends JpaRepository<TestEntity, Long> {}
TestEntity.java
@Entity
@Table(name = "ent")
public class TestEntity {
@Id
@GeneratedValue(strategy = GenerationType.IDENTITY)
private Long id;
private String descript;
//equals, hashcode, toString, getters, setters
}
AppInitializer.java
public class AppInitializer extends AbstractAnnotationConfigDispatcherServletInitializer {
private WebApplicationContext rootContext;
@Override
protected Class<?>[] getRootConfigClasses() {
return new Class[]{ApplicationConfig.class};
}
@Override
protected Class<?>[] getServletConfigClasses() {
return null;
}
@Override
protected String[] getServletMappings() {
return new String[]{"/"};
}
}
命令
jmap -histo <tomcat_pid>
tomcat 停止后仅显示项目结构中的 2 项:
com.test.config.dao.JPAConfiguration$$EnhancerBySpringCGLIB$$792cb231$$FastClassBySpringCGLIB$$45ff499c
com.test.config.dao.JPAConfiguration$$FastClassBySpringCGLIB$$10104c1e
有人有解决此问题的想法或建议吗?
【问题讨论】:
-
此链接可能会有所帮助stackoverflow.com/questions/40040289/…
-
对于初学者来说,停止覆盖
onStartup和createRootApplicationContext您正在创建一个几乎无用的附加上下文,并且还删除了该字段。你正试图变得聪明,这会扰乱生命周期。我还建议删除不需要的setDriverClassName行,因为 JDBC 几乎能够根据 URL 找出驱动程序。 -
感谢您的回复。 @M.Deinum,我删除了
onStartup和createRootApplicationContext方法,但没有帮助。 Tomcat 仍然显示有关内存泄漏的消息。尝试删除setDriverClassName,但出现异常org.hibernate.engine.jdbc.spi.SqlExceptionHelper.logExceptions Cannot create JDBC driver of class "" for connect URL "jdbc:mysql://localhost:3306/test" -
GitHub 存储库,来源为 github.com/egotovko/tomcat-leak
-
鉴于上面的 git,我在本地机器上停止 tomcat 时没有发现内存泄漏。你能详细说明一下吗?你做了什么?
标签: mysql spring hibernate tomcat memory-leaks