我有一个使用Spring Data的java网站提供与MongoDB的集成。 应用程序运行良好,但不断累积线程,直到服务器最终出现此错误:
org.springframework.beans.factory.BeanCreationException: Error creating bean with name 'mongo': Invocation of init method failed; nested exception is java.lang.OutOfMemoryError: unable to create new native thread
2013-10-15T14:51:40.305986+00:00 app[web.1]: org.springframework.beans.factory.BeanCreationException: Error creating bean with name 'mongo': Invocation of init method failed; nested exception is java.lang.OutOfMemoryError: unable to create new native thread
2013-10-15T14:51:40.305986+00:00 app[web.1]: 1343234 [http-nio-55996-exec-6] DEBUG org.springframework.web.servlet.DispatcherServlet - Could not complete request
2013-10-15T14:51:40.305986+00:00 app[web.1]: at org.springframework.beans.factory.support.AbstractAutowireCapableBeanFactory.initializeBean(AbstractAutowireCapableBeanFactory.java:1455)
2013-10-15T14:51:40.305986+00:00 app[web.1]: at org.springframework.beans.factory.support.AbstractAutowireCapableBeanFactory.createBean(AbstractAutowireCapableBeanFactory.java:456)
2013-10-15T14:51:40.305986+00:00 app[web.1]: at org.springframework.beans.factory.support.AbstractBeanFactory$1.getObject(AbstractBeanFactory.java:294)
2013-10-15T14:51:40.305986+00:00 app[web.1]: at org.springframework.beans.factory.support.AbstractBeanFactory.doGetBean(AbstractBeanFactory.java:291)
2013-10-15T14:51:40.305986+00:00 app[web.1]: at org.springframework.beans.factory.support.AbstractAutowireCapableBeanFactory.doCreateBean(AbstractAutowireCapableBeanFactory.java:519)
2013-10-15T14:51:40.305986+00:00 app[web.1]: at org.springframework.beans.factory.support.DefaultSingletonBeanRegistry.getSingleton(DefaultSingletonBeanRegistry.java:225)
2013-10-15T14:51:40.306169+00:00 app[web.1]: at org.springframework.context.support.AbstractApplicationContext.finishBeanFactoryInitialization(AbstractApplicationContext.java:918)
2013-10-15T14:51:40.306169+00:00 app[web.1]: at org.springframework.contex
t.support.GenericXmlApplicationContext.<init>(GenericXmlApplicationContext.java:71)
2013-10-15T14:51:40.305986+00:00 app[web.1]: at org.springframework.beans.factory.support.AbstractBeanFactory.getBean(AbstractBeanFactory.java:193)
2013-10-15T14:51:40.305986+00:00 app[web.1]: at org.springframework.beans.factory.support.DefaultListableBeanFactory.preInstantiateSingletons(DefaultListableBeanFactory.java:591)
2013-10-15T14:51:40.306169+00:00 app[web.1]: at sun.reflect.NativeMethodAccessorImpl.invoke0(Native Method)
2013-10-15T14:51:40.306334+00:00 app[web.1]: at org.springframework.web.servlet.mvc.annotation.AnnotationMethodHandlerAdapter.handle(AnnotationMethodHandlerAdapter.java:424)
2013-10-15T14:51:40.306169+00:00 app[web.1]: at org.springframework.context.support.AbstractApplicationContext.refresh(AbstractApplicationContext.java:469)
2013-10-15T14:51:40.306169+00:00 app[web.1]: at com.jux.model.Signin.persistSignin(Signin.java:40)
2013-10-15T14:51:40.306169+00:00 app[web.1]: at com.intuit.controller.LoginController.authenticateUser(LoginController.java:71)
2013-10-15T14:51:40.306169+00:00 app[web.1]: at java.lang.reflect.Method.invoke(Method.java:616)
2013-10-15T14:51:40.306169+00:00 app[web.1]: at org.springframework.web.bind.annotation.support.HandlerMethodInvoker.invokeHandlerMethod(HandlerMethodInvoker.java:176)
2013-10-15T14:51:40.306334+00:00 app[web.1]: at org.springframework.web.servlet.FrameworkServlet.
processRequest(FrameworkServlet.java:882)
2013-10-15T14:51:40.306334+00:00 app[web.1]: at org.springframework.web.servlet.FrameworkServlet.doPost(FrameworkServlet.java:789)
2013-10-15T14:51:40.306169+00:00 app[web.1]: at sun.reflect.NativeMethodAccessorImpl.invoke(NativeMethodAccessorImpl.java:57)
2013-10-15T14:51:40.306169+00:00 app[web.1]: at sun.reflect.DelegatingMethodAccessorImpl.invoke(DelegatingMethodAccessorImpl.java:43)
2013-10-15T14:51:40.306334+00:00 app[web.1]: at javax.servlet.http.HttpServlet.service(HttpServlet.java:728)
2013-10-15T14:51:40.306334+00:00 app[web.1]: at org.springframework.web.servlet.DispatcherServlet.doService(DispatcherServlet.java:852)
2013-10-15T14:51:40.306334+00:00 app[web.1]: at org.springframework.web.servlet.mvc.annotation.AnnotationMethodHandlerAdapter.invokeHandlerMethod(AnnotationMethodHandlerAdapter.java:436)
2013-10-15T14:51:40.306334+00:00 app[web.1]: at org.apache.catalina.core.ApplicationFilterChain.internalDoFilter(ApplicationFilterChain.java:305)
2013-10-15T14:51:40.306727+00:00 app[web.1]: at org.apache.catalina.authenticator.AuthenticatorBase.invoke(AuthenticatorBase.java:472)
2013-10-15T14:51:40.306334+00:00 app[web.1]: at org.apache.catalina.core.ApplicationFilterChain.doFilter(ApplicationFilterChain.java:210)
2013-10-15T14:51:40.306334+00:00 app[web.1]: at org.springframework.web.servlet.DispatcherServlet.doDispatch(DispatcherServlet.java:923)
2013-10-15T14:51:40.306727+00:00 app[web.1]: at org.apache.catalina.valves.ErrorReportValve.invoke(ErrorReportValve.java:99)
2013-10-15T14:51:40.306727+00:00 app[web.1]: at org.apache.catalina.connector.CoyoteAdapter.service(CoyoteAdapter.java:408)
2013-10-15T14:51:40.306334+00:00 app[web.1]: at javax.servlet.http.HttpServlet.service(HttpServlet.java:647)
2013-10-15T14:51:40.306727+00:00 app[web.1]: at org.apache.catalina.core.StandardHostValve.invoke(StandardHostValve.java:171)
2013-10-15T14:51:40.306875+00:00 app[web.1]: at java.util.concurrent.ThreadPoolExecutor.runWorker(ThreadPoolExecutor.java:1146)
2013-10-15T14:51:40.306875+00:00 app[web.1]: Caused by: java.lang.OutOfMemoryError: unable to create new native thread
2013-10-15T14:51:40.306875+00:00 app[web.1]: at java.lang.Thread.start0(Native Method)
2013-10-15T14:51:40.306727+00:00 app[web.1]: at org.apache.catalina.core.StandardEngineValve.invoke(StandardEngineValve.java:118)
2013-10-15T14:51:40.306727+00:00 app[web.1]: at org.apache.catalina.core.StandardWrapperValve.invoke(StandardWrapperValve.java:222)
2013-10-15T14:51:40.306875+00:00 app[web.1]: at com.mongodb.Mongo.<init>(Mongo.java:192)
2013-10-15T14:51:40.306875+00:00 app[web.1]: at java.lang.Thread.start(Thread.java:657)
我试图更新我正在使用的Spring Data版本,并尝试使用1.3.1.RELEASE和1.3.2.BUILD-SNAPSHOT - 同样的问题。
我还读过Mongo驱动程序应该关闭这些线程,我不需要在关闭线程上完成任何工作,但我开始怀疑。 知道如何解决这个问题吗?
这是我的mongodb.xml
<?xml version="1.0" encoding="UTF-8"?>
<beans xmlns="http://www.springframework.org/schema/beans"
xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
xmlns:context="http://www.springframework.org/schema/context"
xmlns:mongo="http://www.springframework.org/schema/data/mongo"
xsi:schemaLocation=
"http://www.springframework.org/schema/context
http://www.springframework.org/schema/context/spring-context-3.0.xsd
http://www.springframework.org/schema/data/mongo
http://www.springframework.org/schema/data/mongo/spring-mongo-1.0.xsd
http://www.springframework.org/schema/beans
http://www.springframework.org/schema/beans/spring-beans-3.0.xsd">
<!-- Default bean name is 'mongo' -->
<mongo:mongo host="xxxxxx.mongolab.com" port="12345">
<mongo:options connections-per-host="8"
threads-allowed-to-block-for-connection-multiplier="4"
connect-timeout="1000"
max-wait-time="1500"
auto-connect-retry="true"
socket-keep-alive="true"
socket-timeout="1500"
slave-ok="true"
write-number="1"
write-timeout="0"
write-fsync="true"/>
</mongo:mongo>
<mongo:db-factory id="myMongoDbFactory"
host="xxxxx.mongolab.com"
port="12345"
dbname="zzzz"
username="yyyy"
password="xxxx"/>
<bean id="mongoTemplate" class="org.springframework.data.mongodb.core.MongoTemplate">
<constructor-arg ref="myMongoDbFactory"/>
</bean>
</beans>
这是我在控制器中对MongoDB进行查询的方式:
@RequestMapping(value = "/deletePart.htm", method = RequestMethod.GET)
public String deletePart(String part_id) {
LOG.debug("in deletePart, part_id: "+part_id);
ApplicationContext ctx = new GenericXmlApplicationContext("mongodb.xml");
MongoOperations mongoOps = (MongoOperations)ctx.getBean("mongoTemplate");
Part p = mongoOps.findOne(new Query(where("id").is(part_id)), Part.class);
mongoOps.remove(p);
return "redirect:/parts.htm";
}
以下是线程如何累积并永不关闭的图片:
并从线程转储中,这是一个挂起线程的详细信息:
"MongoCleaner1448498515" daemon prio=5 tid=0x00007f939f888000 nid=0x12f03 waiting on condition [0x00000001ac920000]
java.lang.Thread.State: TIMED_WAITING (sleeping)
at java.lang.Thread.sleep(Native Method)
at com.mongodb.Mongo$CursorCleanerThread.run(Mongo.java:770)
Locked ownable synchronizers:
- None
答案 0 :(得分:1)
我不确定这是否是原因,但您绝对不应为每个请求创建新的上下文。
将mongodb.xml添加到根应用程序上下文中。
答案 1 :(得分:1)
如果关闭应用程序上下文,将关闭Mongo实例并阻止无限制的线程增长:
@RequestMapping(value = "/deletePart.htm", method = RequestMethod.GET)
public String deletePart(String part_id) {
LOG.debug("in deletePart, part_id: "+part_id);
GenericXmlApplicationContext ctx = new GenericXmlApplicationContext("mongodb.xml");
try {
MongoOperations mongoOps = (MongoOperations)ctx.getBean("mongoTemplate");
Part p = mongoOps.findOne(new Query(where("id").is(part_id)), Part.class);
mongoOps.remove(p);
return "redirect:/parts.htm";
} finally {
ctx.close(); // close the context, will close the Mongo instance
}
}
但即使这样可行,您的应用程序仍然不应该为每个请求创建一个应用程序上下文实例。