我有read和read,但他们只是从理论上解释垃圾收集,我认为解释如何解决实际问题一定非常复杂。
我的配置
export JAVA_HOME=/usr/java/jdk6
JAVA_OPTS="-Xms272m -Xmx272m -XX:MaxPermSize=272m -verbose:gc -XX:+PrintGCTimeStamps -XX:+PrintGCDetails"
当服务器启动时,一切顺利如丝
29.846: [GC 29.846: [DefNew: 74109K->1940K(83520K), 0.0125820 secs] 106982K->34813K(269248K), 0.0126230 secs] [Times: user=0.01 sys=0.00, real=0.01 secs]
30.002: [GC 30.002: [DefNew: 76016K->1502K(83520K), 0.0092930 secs] 108889K->34375K(269248K), 0.0093380 secs] [Times: user=0.00 sys=0.00, real=0.01 secs]
31.745: [GC 31.745: [DefNew: 75443K->4722K(83520K), 0.0369630 secs] 108316K->37595K(269248K), 0.0370130 secs] [Times: user=0.02 sys=0.00, real=0.04 secs]
33.122: [GC 33.122: [DefNew: 78962K->6065K(83520K), 0.0444350 secs] 111835K->39481K(269248K), 0.0444850 secs] [Times: user=0.03 sys=0.00, real=0.04 secs]
34.183: [GC 34.183: [DefNew: 80258K->4880K(83520K), 0.0371350 secs] 113674K->41044K(269248K), 0.0371830 secs] [Times: user=0.03 sys=0.00, real=0.03 secs]
未收集的内存量增加,有时会执行一些完整的gc,但系统会从这些内容中恢复
356.210: [Full GC 356.210: [Tenured: 74012K->66067K(185728K), 0.2215880 secs] 126231K->66067K(269248K), [Perm : 70207K->70207K(70208K)], 0.2216510 secs] [Times: user=0.22 sys=0.00, real=0.22 secs]
最后它只执行完整的gc
61587.386: [Full GC 61587.386: [Tenured: 185728K->185728K(185728K), 0.4045190 secs] 269107K->188117K(269248K), [Perm : 85394K->85394K(85504K)], 0.4045860 secs] [Times: user=0.40 sys=0.00, real=0.41 secs]
61587.820: [Full GC 61587.820: [Tenured: 185728K->185728K(185728K), 0.4075960 secs] 268851K->187688K(269248K), [Perm : 85394K->85394K(85504K)], 0.4076610 secs] [Times: user=0.40 sys=0.00, real=0.41 secs]
61588.258: [Full GC 61588.258: [Tenured: 185728K->185727K(185728K), 0.4184530 secs] 269042K->187217K(269248K), [Perm : 85394K->85248K(85504K)], 0.4185420 secs] [Times: user=0.41 sys=0.00, real=0.41 secs]
61588.702: [Full GC 61588.702: [Tenured: 185727K->185727K(185728K), 0.4054800 secs] 269129K->187216K(269248K), [Perm : 85248K->85248K(85504K)], 0.4055560 secs] [Times: user=0.40 sys=0.00, real=0.41 secs]
61589.145: [Full GC 61589.145: [Tenured: 185727K->185727K(185728K), 0.4042100 secs] 269048K->187247K(269248K), [Perm : 85248K->85248K(85504K)], 0.4042770 secs] [Times: user=0.40 sys=0.00, real=0.41 secs]
和例外出现
Jun 10, 2015 5:12:24 PM org.apache.catalina.core.ApplicationDispatcher invoke
SEVERE: Servlet.service() for servlet jsp threw exception
java.lang.IllegalStateException: Cannot create a session after the response has been committed
Web应用程序在Tomcat 7 Server上运行Java 1.6并使用Struts 2(2.3.24)任何帮助都会非常感激,因为我只是一个java程序员而且我不知道java有这些重要的警告引擎盖。感谢
答案 0 :(得分:2)
您的问题比完整的GC更为重要。您甚至没有尝试了解当前正在发生的事情,即当前的默认设置适用,更不用说更改默认设置。
此外,完整的GC本身并不一定是坏事。
-Xmx272m
这是最大堆大小。即允许应用程序使用的最大堆量。您链接的指南有这个主题的几个章节。
你不了解哪部分指南?
DefNew
这是连续的年轻一代收藏家。它的单线程(读:慢)
[时间:用户= 0.41 sys = 0.00,实际= 0.41秒]
user == real time也意味着单线程旧的gen gen。
java 6早已达到人生的终点。更新到java 8,它提供了新的和改进的收集器导出JAVA_HOME = / usr / java / jdk6
我已阅读并阅读,但他们只是从理论上解释垃圾收集
您链接的指南解释了许多可用的选项,而不仅仅是学术理论。看起来您甚至没有尝试过任何选项。
因为我只是一名java程序员而且我并不知道java有这些重要的警告。
GC实际上是java的一部分。作为程序员,您需要了解它,因为忽略它会使您的应用程序崩溃或无法正常执行。
如果您认为您不需要知道自己错了。
答案 1 :(得分:1)
有两种策略可以阻止完整的gc:
1)尽量减少长寿命物体的数量。完全归零。如果你存储链接到某个对象的时间超过年轻的gc间隔,那个对象将在堆中生存直到完全gc。通常,在没有长寿命对象的情况下完全创建Java应用程序是不可能的,但是你可以减少它的数量。
最糟糕的情况是,当你的应用程序生成长寿命对象并且永远不会释放它时,它就像内存泄漏并导致内存错误
2)放大堆和年轻代的大小(第一个给你更多的时间在gc之前,第二个放大间隔年轻的gc(不太长寿的对象)。通过重新启动应用程序(例如基于堆大小)防止完全gc。小心翼翼。年轻的年轻人会对年轻的gc造成更大的停顿。
现代G1 gc(Java 8中的默认值?)应该减少完整gc调用的次数
我有使用10G年轻Gen 60G堆的应用程序的经验,最大堆大小超过200GB。完整的gc从未打过电话(我们每隔2-5天重启一次)。年轻的gc每1-5分钟暂停0.1-0.3秒。