Results 1 to 6 of 6

Thread: Spring + MyBatis + Tomcat 7 = memory leak

  1. #1
    Join Date
    Jan 2013
    Posts
    4

    Default Spring + MyBatis + Tomcat 7 = memory leak ?

    Hi All,

    I currently having the following memory leaks

    Code:
    Jan 15, 2013 2:33:34 PM org.apache.catalina.loader.WebappClassLoader clearReferencesThreads
    SEVERE: The web application [/ArcaneAeon] appears to have started a thread named [com.google.common.base.internal.Finalizer] but has failed to stop it. This is very likely to create a memory leak.
    Jan 15, 2013 2:33:34 PM org.apache.catalina.loader.WebappClassLoader clearReferencesThreads
    SEVERE: The web application [/ArcaneAeon] appears to have started a thread named [Memcached IO over {MemcachedConnection to /221.133.9.157:10000}] but has failed to stop it. This is very likely to create a memory leak.
    Jan 15, 2013 2:33:34 PM org.apache.catalina.loader.WebappClassLoader checkThreadLocalMapForLeaks
    SEVERE: The web application [/ArcaneAeon] created a ThreadLocal with key of type [jsr166y.ThreadLocalRandom$1] (value [jsr166y.ThreadLocalRandom$1@2bc6a19f]) and a value of type [jsr166y.ThreadLocalRandom] (value [jsr166y.ThreadLocalRandom@7d9ce42c]) but failed to remove it when the web application was stopped. Threads are going to be renewed over time to try and avoid a probable memory leak.
    Jan 15, 2013 2:33:34 PM org.apache.catalina.loader.WebappClassLoader checkThreadLocalMapForLeaks
    SEVERE: The web application [/ArcaneAeon] created a ThreadLocal with key of type [java.lang.ThreadLocal] (value [java.lang.ThreadLocal@47484521]) and a value of type [org.apache.ibatis.jdbc.SqlBuilder.SQL] (value [org.apache.ibatis.jdbc.SqlBuilder$SQL@59b29e16]) but failed to remove it when the web application was stopped. Threads are going to be renewed over time to try and avoid a probable memory leak.
    Jan 15, 2013 2:33:34 PM org.apache.catalina.loader.WebappClassLoader checkThreadLocalMapForLeaks
    SEVERE: The web application [/ArcaneAeon] created a ThreadLocal with key of type [jsr166y.ThreadLocalRandom$1] (value [jsr166y.ThreadLocalRandom$1@2bc6a19f]) and a value of type [jsr166y.ThreadLocalRandom] (value [jsr166y.ThreadLocalRandom@5da8e45b]) but failed to remove it when the web application was stopped. Threads are going to be renewed over time to try and avoid a probable memory leak.
    Jan 15, 2013 2:33:34 PM org.apache.catalina.loader.WebappClassLoader checkThreadLocalMapForLeaks
    SEVERE: The web application [/ArcaneAeon] created a ThreadLocal with key of type [java.lang.ThreadLocal] (value [java.lang.ThreadLocal@47484521]) and a value of type [org.apache.ibatis.jdbc.SqlBuilder.SQL] (value [org.apache.ibatis.jdbc.SqlBuilder$SQL@7b284266]) but failed to remove it when the web application was stopped. Threads are going to be renewed over time to try and avoid a probable memory leak.
    Jan 15, 2013 2:33:34 PM org.apache.catalina.loader.WebappClassLoader checkThreadLocalMapForLeaks
    SEVERE: The web application [/ArcaneAeon] created a ThreadLocal with key of type [java.lang.ThreadLocal] (value [java.lang.ThreadLocal@47484521]) and a value of type [org.apache.ibatis.jdbc.SqlBuilder.SQL] (value [org.apache.ibatis.jdbc.SqlBuilder$SQL@101f75b5]) but failed to remove it when the web application was stopped. Threads are going to be renewed over time to try and avoid a probable memory leak.
    The number of SQLBuilder leaks increase as the number of database accesses increase.

    any help is highly appreciated.
    Last edited by eviljan; Jan 15th, 2013 at 10:44 AM.

  2. #2
    Join Date
    Jun 2006
    Location
    The Netherlands
    Posts
    13,632

    Default

    And why is this a spring issue? Spring doesn't have MyBatis integration that is provided by the MyBatis project itself not Spring so to address these issues you really have to be on that project...
    Marten Deinum
    Java Consultant / Pragmatist / Open Source Enthousiast / Author


    Pro Spring MVC: With Web Flow
    Conspect

    Have you read the reference guide.
    Use the [ code ] tags, young padawan

  3. #3
    Join Date
    Jan 2013
    Posts
    4

    Default

    Quote Originally Posted by Marten Deinum View Post
    And why is this a spring issue? Spring doesn't have MyBatis integration that is provided by the MyBatis project itself not Spring so to address these issues you really have to be on that project...
    I posted here since I have not found any discussion regarding to this kind of leak. It might be my misconfiguration of Spring + Mybatis and therefore asking for your experience.

  4. #4
    Join Date
    Jun 2006
    Location
    The Netherlands
    Posts
    13,632

    Default

    Without configuration that is hard to tell. Also what you see is an indication it doesn't have to be a memory leak (probably is if you hot redeploy your application).
    Marten Deinum
    Java Consultant / Pragmatist / Open Source Enthousiast / Author


    Pro Spring MVC: With Web Flow
    Conspect

    Have you read the reference guide.
    Use the [ code ] tags, young padawan

  5. #5
    Join Date
    Jan 2013
    Posts
    4

    Default

    Quote Originally Posted by Marten Deinum View Post
    Without configuration that is hard to tell. Also what you see is an indication it doesn't have to be a memory leak (probably is if you hot redeploy your application).
    Thank all,

    It's not hot deploy tho. Those happen when I stop the server and it seems that the SQLBuilder + jsr166y.ThreadLocalRandom warnings increase as you have more data accessing to the database.

    here is the configuration file

    root-context.xml
    Code:
    <?xml version="1.0" encoding="UTF-8"?>
    <beans xmlns="http://www.springframework.org/schema/beans"
        xmlns:p="http://www.springframework.org/schema/p"
    	xmlns:context="http://www.springframework.org/schema/context"
        xmlns:security="http://www.springframework.org/schema/security"
    	xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" 
    	xsi:schemaLocation="
    			http://www.springframework.org/schema/beans http://www.springframework.org/schema/beans/spring-beans.xsd
    			http://www.springframework.org/schema/context http://www.springframework.org/schema/context/spring-context.xsd
                http://www.springframework.org/schema/security http://www.springframework.org/schema/security/spring-security.xsd">
    
    	<!-- Root Context: defines shared resources visible to all other web components -->
    	<context:annotation-config /> 
    	<context:component-scan base-package="com.firefly.lcgame" />
    	
    	<!-- Load Properties Files -->
    	<context:property-placeholder location="classpath:*-${environment}.properties"/>
    
    	<!-- Spring Data Redis -->
    	<bean id="connectionFactory"
    		class="org.springframework.data.redis.connection.jedis.JedisConnectionFactory">
    		<property name="hostName" value="${redis.host}" />
    		<property name="port" value="${redis.port}" />
    		<property name="password" value="${redis.pass}" />
    		<property name="usePool" value="${redis.pooling}" />
    		<property name="poolConfig" ref="jedisPoolConfig" />
    	</bean>
    	<bean id="jedisPoolConfig" class="redis.clients.jedis.JedisPoolConfig">
    		<property name="maxActive" value="${redis.maxActive}" />
    		<property name="minIdle" value="${redis.minIdle}" />
    		<property name="testOnBorrow" value="${redis.testOnBorrow}" />
    	</bean>
    
    	<bean id="redisTemplate" class="org.springframework.data.redis.core.RedisTemplate">
    	    <property name="connectionFactory" ref="connectionFactory"/>
    	    <property name="keySerializer">
    	        <bean id="keyStringSerializer" class="org.springframework.data.redis.serializer.StringRedisSerializer"/>
    	    </property>
    	</bean>
    	
    	<!-- BoneCP configuration -->
    	<bean id="dataSource" class="com.jolbox.bonecp.BoneCPDataSource" destroy-method="close">
    		<property name="driverClass" value="${jdbc.driverClassName}" />
    		<property name="jdbcUrl" value="${jdbc.url}" />
    		<property name="username" value="${jdbc.username}"/>
    		<property name="password" value="${jdbc.password}"/>
    		<property name="idleConnectionTestPeriodInMinutes" value="${boneCP.idleConnectionTestPeriodInMinutes}"/>
    		<property name="idleMaxAgeInMinutes" value="${boneCP.idleMaxAgeInMinutes}"/>
    		<property name="maxConnectionsPerPartition" value="${boneCP.maxConnectionsPerPartition}"/>
    		<property name="minConnectionsPerPartition" value="${boneCP.minConnectionsPerPartition}"/>
    		<property name="partitionCount" value="${boneCP.partitionCount}"/>
    		<property name="acquireIncrement" value="${boneCP.acquireIncrement}"/>
    		<property name="statementsCacheSize" value="${boneCP.statementsCacheSize}"/>
    		<property name="releaseHelperThreads" value="${boneCP.releaseHelperThreads}"/>
    		<property name="lazyInit" value="true"/>
    		<property name="maxConnectionAgeInSeconds" value="${boneCP.maxConnectionAgeInSeconds}"/>
    	</bean>
    
    	<bean id="sqlSessionFactory" class="org.mybatis.spring.SqlSessionFactoryBean">
    		<property name="dataSource" ref="dataSource" />
    		<property name="configLocation" value="classpath:mybatis-config.xml" />
    	</bean>
    
    	<bean id="transactionManager"
    		class="org.springframework.jdbc.datasource.DataSourceTransactionManager">
    		<property name="dataSource" ref="dataSource" />
    	</bean>
    
    	<bean id="mappers" class="org.mybatis.spring.mapper.MapperScannerConfigurer">
    		<property name="basePackage" value="com.firefly.lcgame.dao" />
    		<!-- <property name="sqlSessionFactoryBeanName" value="sqlSessionFactory" /> -->
    	</bean>
        
        <bean class="org.springframework.web.servlet.mvc.annotation.DefaultAnnotationHandlerMapping"/>
    
    	<bean
    		class="org.springframework.web.servlet.mvc.annotation.AnnotationMethodHandlerAdapter">
    		<property name="messageConverters">
    			<list>
    				<ref bean="jsonConverter" />
    				<!-- <ref bean="marshallingConverter" />
    				<ref bean="atomConverter" /> -->
    			</list>
    		</property>
    	</bean>
    
    	<bean id="jsonConverter"
    		class="org.springframework.http.converter.json.MappingJacksonHttpMessageConverter">
    		<property name="supportedMediaTypes" value="application/json" />
    	</bean>
        
        <bean id="localeResolver" class="org.springframework.web.servlet.i18n.AcceptHeaderLocaleResolver"/>
    
        <!-- localization -->
        <bean id="messageSource" class="org.springframework.context.support.ReloadableResourceBundleMessageSource"
          p:fallbackToSystemLocale="false" p:useCodeAsDefaultMessage="true" p:defaultEncoding="UTF-8">
          <description>Base message source to handle internationalization</description>
          <property name="basenames">
            <list>
              <value>classpath:localization/messages</value>
            </list>
          </property>
        </bean>
    
        <bean id="annotationMethodHandlerExceptionResolver" class="org.springframework.web.servlet.mvc.annotation.AnnotationMethodHandlerExceptionResolver">
          <property name="order" value="0"/>
        </bean>
        <bean id="restExceptionResolver" class="com.firefly.lcgame.exceptions.handler.RestExceptionHandler">
          <property name="order" value="100"></property>
          <property name="errorResolver">
            <bean class="com.firefly.lcgame.exceptions.handler.DefaultRestErrorResolver">
              <property name="localeResolver" ref="localeResolver"></property>
              <!-- <property name="defaultMoreInfoUrl" value="mailto:support@mycompany.com"></property> -->
              <property name="exceptionMappingDefinitions">
                <map>
                  <!-- 404 -->
                  <entry key="com.firefly.lcgame.exceptions.InvalidAccessExeption" value="404, 1, error.invalid.access,  _exmsg"></entry>
                  <!-- 500 (catch all): -->
                  <entry key="Throwable" value="500, 1, error.internal, _exmsg"></entry>
                </map>
              </property>
            </bean>
          </property>
        </bean>
      
      <!-- Secure Rest Service Configuration -->
        <!-- <security:http create-session="never" entry-point-ref="digestEntryPoint">
          <security:intercept-url pattern="/duty/stages**" access="ROLE_USER, ROLE_ADMIN" />
          <security:http-basic />
          <security:custom-filter ref="digestFilter" after="BASIC_AUTH_FILTER" />
        </security:http> -->
        
        <security:http pattern="/login**"  security="none">
        </security:http>
    
        <security:http pattern="/dummy**">
          <security:intercept-url pattern="/dummy**" access="ROLE_USER, ROLE_ADMIN"/>
          <security:http-basic/>
        </security:http>
    
        <security:http pattern="/**" entry-point-ref="digestEntryPoint" >
          <security:intercept-url pattern="/**" access="ROLE_USER, ROLE_ADMIN"/>
          <security:custom-filter ref="digestFilter" position="BASIC_AUTH_FILTER"/>
        </security:http>
        
        <bean id="digestFilter" class="org.springframework.security.web.authentication.www.DigestAuthenticationFilter">
           <property name="userDetailsService" ref="userService" />
           <property name="authenticationEntryPoint" ref="digestEntryPoint" />
        </bean>
     
        <bean id="digestEntryPoint" class="org.springframework.security.web.authentication.www.DigestAuthenticationEntryPoint">
          <property name="realmName" value="Arcane Aeon Digest Secure REST-WS"/>
          <property name="key" value="xxxxxxxxxxxx"/>
          <property name="nonceValiditySeconds" value="10"/>
        </bean>
        
        <security:authentication-manager>
          <security:authentication-provider user-service-ref="userService"/>
        </security:authentication-manager>
        
        <bean id="userService" class="com.firefly.lcgame.services.CustomerUserDetailsService">
        </bean>
        
        <bean id="connectionManager" class="org.apache.http.impl.conn.PoolingClientConnectionManager" destroy-method="shutdown">
            <property name="defaultMaxPerRoute" value="${http.defaultMaxPerRoute}" />
            <property name="maxTotal" value="${http.maxTotal}" />
        </bean>
    
        <bean id="httpClient" class="com.firefly.lcgame.util.ThreadedHttpClient">
            <property name="connectionManager" ref="connectionManager" />
        </bean>
    </beans>

  6. #6
    Join Date
    Jan 2013
    Posts
    4

    Default

    Quote Originally Posted by Marten Deinum View Post
    Without configuration that is hard to tell. Also what you see is an indication it doesn't have to be a memory leak (probably is if you hot redeploy your application).
    Hi Marten,

    I think it's memory leak because the number of SQLBuilder and jsr166y.ThreadLocalRandom threads increases overtime. The more the database is accessed, the more of those I found when I stop the server

    here is part of the config regarding to Mybatis
    Code:
    <!-- BoneCP configuration -->
    	<bean id="dataSource" class="com.jolbox.bonecp.BoneCPDataSource" destroy-method="close">
    		<property name="driverClass" value="${jdbc.driverClassName}" />
    		<property name="jdbcUrl" value="${jdbc.url}" />
    		<property name="username" value="${jdbc.username}"/>
    		<property name="password" value="${jdbc.password}"/>
    		<property name="idleConnectionTestPeriodInMinutes" value="${boneCP.idleConnectionTestPeriodInMinutes}"/>
    		<property name="idleMaxAgeInMinutes" value="${boneCP.idleMaxAgeInMinutes}"/>
    		<property name="maxConnectionsPerPartition" value="${boneCP.maxConnectionsPerPartition}"/>
    		<property name="minConnectionsPerPartition" value="${boneCP.minConnectionsPerPartition}"/>
    		<property name="partitionCount" value="${boneCP.partitionCount}"/>
    		<property name="acquireIncrement" value="${boneCP.acquireIncrement}"/>
    		<property name="statementsCacheSize" value="${boneCP.statementsCacheSize}"/>
    		<property name="releaseHelperThreads" value="${boneCP.releaseHelperThreads}"/>
    		<property name="lazyInit" value="true"/>
    		<property name="maxConnectionAgeInSeconds" value="${boneCP.maxConnectionAgeInSeconds}"/>
    	</bean>
    
    	<bean id="sqlSessionFactory" class="org.mybatis.spring.SqlSessionFactoryBean">
    		<property name="dataSource" ref="dataSource" />
    		<property name="configLocation" value="classpath:mybatis-config.xml" />
    	</bean>
    
    	<bean id="transactionManager"
    		class="org.springframework.jdbc.datasource.DataSourceTransactionManager">
    		<property name="dataSource" ref="dataSource" />
    	</bean>
    
    	<bean id="mappers" class="org.mybatis.spring.mapper.MapperScannerConfigurer">
    		<property name="basePackage" value="com.firefly.lcgame.dao" />
    		<!-- <property name="sqlSessionFactoryBeanName" value="sqlSessionFactory" /> -->
    	</bean>
    mybatis config
    Code:
    <?xml version="1.0" encoding="UTF-8" ?>
    <!DOCTYPE configuration
      PUBLIC "-//mybatis.org//DTD Config 3.0//EN"
      "http://mybatis.org/dtd/mybatis-3-config.dtd">
    <configuration>
    	<settings>
    		<setting name="lazyLoadTriggerMethods" value="equals,clone,hashCode,toString" />
    		<setting name="lazyLoadingEnabled" value="true" />
    		<setting name="defaultExecutorType" value="SIMPLE" />
    		<setting name="defaultStatementTimeout" value="25000" />
    	</settings>
    </configuration>
    Last edited by eviljan; Jan 15th, 2013 at 10:02 PM.

Tags for this Thread

Posting Permissions

  • You may not post new threads
  • You may not post replies
  • You may not post attachments
  • You may not edit your posts
  •