【发布时间】:2012-06-11 14:16:32
【问题描述】:
我运行的是Tomcat7,服务器相当强大,8 GB RAM 8-core。
我的问题是RES内存越来越高,直到服务器不再响应,甚至没有调用OnOutOfMemoryError。
Tomcat 配置:
-Xms1024M
-Xmx2048M
-XX:PermSize=256m
-XX:MaxPermSize=512m
-XX:+UseConcMarkSweepGC
-XX:OnOutOfMemoryError='/var/tomcat/conf/restart_tomcat.sh'
内存信息:
Memory: Non heap memory = 106 Mb (Perm Gen, Code Cache),
Loaded classes = 14,055,
Garbage collection time = 47,608 ms,
Process cpu time = 4,296,860 ms,
Committed virtual memory = 6,910 Mb,
Free physical memory = 4,906 Mb,
Total physical memory = 8,192 Mb,
Free swap space = 26,079 Mb,
Total swap space = 26,079 Mb
Perm Gen memory: 88 Mb / 512 Mb ++++++++++++
Free disk space: 89,341 Mb
Tomcat 使用的内存与 top 命令相比看起来并没有那么高。
在尝试连接到 SMTP 服务器或尝试连接到 facebook 服务器时,我也收到了 java.net.SocketException: No buffer space available。
我使用 Hibernate,带有 c3p0 连接池,配置如下:
<property name="hibernate.connection.driver_class">com.mysql.jdbc.Driver</property>
<property name="hibernate.connection.url">jdbc:mysql://urldb/schema?autoReconnect=true</property>
<property name="hibernate.connection.username">username</property>
<property name="hibernate.dialect">org.hibernate.dialect.MySQL5InnoDBDialect</property>
<property name="hibernate.connection.password"></property>
<property name="connection.characterEncoding">UTF-8</property>
<property name="hibernate.c3p0.acquire_increment">1</property>
<property name="hibernate.c3p0.idle_test_period">300</property>
<property name="hibernate.c3p0.timeout">5000</property>
<property name="hibernate.c3p0.max_size">50</property>
<property name="hibernate.c3p0.min_size">1</property>
<property name="hibernate.c3p0.max_statement">0</property>
<property name="hibernate.c3p0.preferredTestQuery">select 1;</property>
<property name="hibernate.connection.provider_class">org.hibernate.connection.C3P0ConnectionProvider</property>
我找不到任何东西...有人暗示我应该在哪里寻找吗?
谢谢!
[更新 1]堆转储:
HEAP HISTOGRAM :
class [C 269780 34210054
class [B 5600 33836661
class java.util.HashMap$Entry 221872 6212416
class [Ljava.util.HashMap$Entry; 23797 6032056
class java.lang.String 271170 5423400
class org.hibernate.hql.ast.tree.Node 103588 4972224
class net.bull.javamelody.CounterRequest 28809 2996136
class org.hibernate.hql.ast.tree.IdentNode 23461 2205334
class java.lang.Class 14677 2113488
class org.hibernate.hql.ast.tree.DotNode 13045 1852390
class [Ljava.lang.String; 48506 1335600
class [Ljava.lang.Object; 12997 1317016
Instance Counts for All Classes (excluding platform) :
103588 instances of class org.hibernate.hql.ast.tree.Node
33366 instances of class antlr.ANTLRHashString
28809 instances of class net.bull.javamelody.CounterRequest
24436 instances of class org.apache.tomcat.util.buf.ByteChunk
23461 instances of class org.hibernate.hql.ast.tree.IdentNode
22781 instances of class org.apache.tomcat.util.buf.CharChunk
22331 instances of class org.apache.tomcat.util.buf.MessageBytes
13045 instances of class org.hibernate.hql.ast.tree.DotNode
10024 instances of class net.bull.javamelody.JRobin
9084 instances of class org.apache.catalina.loader.ResourceEntry
7931 instances of class org.hibernate.hql.ast.tree.SqlNode
[更新 2] server.xml :
<Connector port="8080" protocol="HTTP/1.1"
connectionTimeout="20000"
redirectPort="8443"
URIEncoding="UTF-8"
maxThreads="150"
minSpareThreads="25"
maxSpareThreads="75"
enableLookups="false"
acceptCount="1024"
server="unknown"
address="public_ip"
/>
****[更新 3] 日志文件的输出:****
2012-06-04 06:18:24,152 [http-bio-ip-8080-exec-3500] ERROR org.apache.catalina.core.ContainerBase.[Catalina].[localhost].[/api].[Jersey REST Service]- Servlet.ser
vice() for servlet [Jersey REST Service] in context with path [/socialapi] threw exception
java.net.SocketTimeoutException: Read timed out
at java.net.SocketInputStream.socketRead0(Native Method)
at java.net.SocketInputStream.read(SocketInputStream.java:129)
at org.apache.coyote.http11.InternalInputBuffer.fill(InternalInputBuffer.java:532)
at org.apache.coyote.http11.InternalInputBuffer.fill(InternalInputBuffer.java:501)
at org.apache.coyote.http11.InternalInputBuffer$InputStreamInputBuffer.doRead(InternalInputBuffer.java:563)
at org.apache.coyote.http11.filters.IdentityInputFilter.doRead(IdentityInputFilter.java:118)
at org.apache.coyote.http11.AbstractInputBuffer.doRead(AbstractInputBuffer.java:326)
at org.apache.coyote.Request.doRead(Request.java:422)
[更新 4] ServletContext
我在我的应用程序中使用ServletContextListener 来实例化控制器并使用event.getServletContext().setAttribute 保持引用。这些控制器加载配置和翻译(Perm 中的 88Mb)。
然后使用我使用的数据库:
SessionFactory sf = dbManager.getSessionFactory(DatabaseManager.DB_KEY_DEFAULT);
Session session = sf.openSession();
Transaction tx = null;
try {
tx = session.beginTransaction();
//Do stuuf
tx.commit();
} catch (Exception e){
//Do something
} finally {
session.close();
}
- 这可能是泄漏源吗?
- 为什么不使用手动事务/会话,你会怎么做?
【问题讨论】:
-
当服务器停止响应时,您还应该获得一个线程转储(请参阅wiki.apache.org/tomcat/…)以查看您的 JVM 实际在做什么。您能否也从 server.xml 发布您的
配置,告诉我们您的 DBCP 中启用的任何“废弃连接”功能,并告诉我们您的 JVM 进程的文件句柄限制是多少?日志中的任何内容——尤其是 logs/catalina.out(或 stdout 所在的任何位置)? -
更新 2:server.xml。好的,谢谢,下次它阻塞时我会尝试 jstack !在我的 mysql 进程列表上,我可以看到一个费用等待连接,这没什么奇怪的。在日志中,我已将其放入更新 3
-
您的应用程序使用了很多 HQL?休眠注释或xml? HQL 最终是静态的吗?
-
HQL 最终是静态的吗?您的应用程序需要多少个线程。你在使用池化吗?
-
HQL 最终静态?不,我正在使用 SessionFactory,处理会话并从会话创建查询并在事务中执行查询。由于它在 tomcat 上运行,因此它是每个请求的线程。我正在使用 C3P0 进行 Mysql 连接池,在调试日志中看起来不错。
标签: java hibernate tomcat tomcat7