Cam*_*e R 7 java tomcat hibernate tomcat7
我正在运行Tomcat7,服务器非常强大,8 GB RAM 8核.

我的问题是RES内存越来越高,直到服务器不再响应,甚至没有调用OnOutOfMemoryError.
Tomcat配置:
-Xms1024M
-Xmx2048M
-XX:PermSize=256m
-XX:MaxPermSize=512m
-XX:+UseConcMarkSweepGC
-XX:OnOutOfMemoryError='/var/tomcat/conf/restart_tomcat.sh'
Run Code Online (Sandbox Code Playgroud)
记忆信息:
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
Run Code Online (Sandbox Code Playgroud)
与top命令相比,Tomcat使用的内存看起来并不高.

我java.net.SocketException: No buffer space available在尝试连接到SMTP服务器或尝试连接到Facebook服务器时也有过.
我使用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>
Run Code Online (Sandbox Code Playgroud)
我找不到任何东西......是否有人暗示我应该寻找什么?
谢谢!
[更新1] HEAP DUMP:
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
Run Code Online (Sandbox Code Playgroud)
[更新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"
/>
Run Code Online (Sandbox Code Playgroud)
****[更新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)
Run Code Online (Sandbox Code Playgroud)
[更新4] ServletContext
我ServletContextListener在我的应用程序中使用一个instanciate控制器并保持引用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();
}
Run Code Online (Sandbox Code Playgroud)
sse*_*ano 14
尝试使用此参数:
+XX:+HeapDumpOnOutOfMemoryError -XX:+HeapDumpPath=dump.log
Run Code Online (Sandbox Code Playgroud)
同时尝试使用较低的启动内存参数-Xms.
然后你可以检查转储,看看问题是否是对象分配.
在运行试试
jps
Run Code Online (Sandbox Code Playgroud)
这将输出所有java进程,假设Tomcat是PID4444:
jmap -dump:format=b,file=heapdump 4444
Run Code Online (Sandbox Code Playgroud)
和
jhat heapdump
Run Code Online (Sandbox Code Playgroud)
如果执行jhat时内存不足,只需添加更多内存.从那里,您可以检查应用程序的堆.
另一种方法是启用Hibernate统计信息以检查您是否检索到更多对象.虽然它看起来像一个完整的垃圾收集每小时应该不是一个问题(在那里做得更好的空间).
-verbose:gc -Xloggc:/opt/tomcat/logs/gc.out -XX:+PrintGCDetails -XX:+PrintGCTimeStamps
Run Code Online (Sandbox Code Playgroud)
例如,使用GCViewer查看内存的每个空间(ternured,eden,survivors,perm).
另一个方便的工具:
jstack 4444 > stack.txt
Run Code Online (Sandbox Code Playgroud)
这将使用pid 4444检索在java进程内运行的每个线程的完整堆栈跟踪.
请记住,如果Tomcat以root用户或其他用户身份启动,则需要权限.
jps
Run Code Online (Sandbox Code Playgroud)
不会输出您没有权限的进程,因此您无法连接到它.
由于我不知道你的应用程序是什么(因此我不知道它的要求),300万个实例看起来很多.
有了Hibernate statistics你可以看到你实例化哪一个类最多.
然后调整eden and ternured垃圾回收的比例可以更有效.
新实例化的对象进入伊甸园.当它填满一个次要的gc触发器.未删除的内容会转移到幸存者空间.当它填满时,它会变得无形.当ternured已满时,将出现完整的gc.
在这张图片中(这是不准确的)我放在一边String,成为实习和内存映射文件(不在堆中).看看你实例化最多的类.密集使用String可能导致快速填满烫发.
我猜你这样做了,但是使用一个托管会话工厂,比如Spring(如果在你的堆栈中)并避免手动管理事务和会话.
请记住,当没有对象引用它时,GC中的对象将被删除.因此,只要您的应用程序中的对象可以访问,该对象就会保留.
如果您的ServletContextListener实例化控制器并存储在事件getServletContext中.确保之后完全删除引用,如果保留引用,则不会删除对象,因为它们仍然可以访问.
如果您管理自己的事务和会话(如果您不能使用框架那么这很好)那么您必须处理代码维护和Spring-tx例如已经解决和改进的错误.
我个人会利用FOSS.但当然有时你不能放大堆栈.
如果你正在使用Hibernate我会看一看Spring-orm并Spring-tx管理交易和会话.另外看一看Hibernate patter Open Session In View.
| 归档时间: |
|
| 查看次数: |
10908 次 |
| 最近记录: |