如何查看GC 及jvm配置

参考 http://desert3.iteye.com/blog/1016470

查看永久区
./jmap -permstat 84012

GC 日志+
jstat – gcutil
Jmap dump +可视化工具(VisualVM/MAT)
Jmap - dump:format=b,file=<filename> 

jmap -dump:format=b,file=jheap30689.bin 30689

[@zw_90_156 ~]$ jps
2407 Resin
10104 Resin
7378 Jps
2360 WatchdogManager
6375 start.jar
16762 Resin
10066 WatchdogManager
[@zw_90_156 ~]$ jstat -gcutil 2407 2s
S0 S1 E O P YGC YGCT FGC FGCT GCT
62.50 0.00 85.70 83.57 99.90 1538 6.043 1 0.056 6.099
62.50 0.00 85.71 83.57 99.90 1538 6.043 1 0.056 6.099
62.50 0.00 85.77 83.57 99.90 1538 6.043 1 0.056 6.099
62.50 0.00 85.77 83.57 99.90 1538 6.043 1 0.056 6.099
62.50 0.00 85.83 83.57 99.90 1538 6.043 1 0.056 6.099
62.50 0.00 85.83 83.57 99.90 1538 6.043 1 0.056 6.099

查看FGC参数 如出现1,2,3,4等 则表明在频繁的FGC


JVM_ARGS: "-Xmx1024m -Xss512k -Xms1024m -XX:ParallelGCThreads=2 -XX:+UseConcMarkSweepGC -XX:+UseParNewGC -XX:CMSInitiatingOccupancyFraction=80 -Dspring.profiles.active=product -XX:MaxPermSize=128m -XX:PermSize=128m

serial 单线程 serial old
parNew 多线程 并行 parNow old
parallel scavenge 多线程并行 parallel old (自适应调节策略) 高吞吐
cms 并发低停顿 (在并发标记和并发清除时与客户线程一起工作)

-XX:+UseConcMarkSweepGC 年老代 cms并发收集器 parNew + cms + serial Old
-XX:+UseParNewGC 新生代 parNew收集器 与cms配合使用 parNew + Serial Old
-XX:ParallelGCThreads=2 限制垃圾收集的线程数

cms 缩短垃圾收集时用户的停顿时间 serial old 年老代 cms的备份
parallel scavenge 新生代 收集器 高吞吐 吞吐量优先
-Xmx 设置最大堆

prallel scavenge 新生代 + parallel old 年老代 吞吐量优先 并行
parNew 并行 + cms 最短停顿时间 并发低停顿收集器


-XX:CMSInitiatingOccupancyFraction=80 cms收集器在年老代使用80%后被激活

-Xmx1024m -Xms1024m java堆heap大小

======================================

[@zw-90-156 ~]$ jps -l
15210 com.caucho.boot.WatchdogManager
28290 sun.tools.jps.Jps
10551 com.caucho.server.resin.Resin
7164 com.caucho.boot.WatchdogManager
14309 com.caucho.server.resin.Resin
1282 com.caucho.server.resin.Resin
28193 com.caucho.server.resin.Resin
9335 com.caucho.boot.WatchdogManager
16246 com.caucho.server.resin.Resin
8554 com.caucho.boot.WatchdogManager
13769 /opt/jetty_dev/start.jar
1242 com.caucho.boot.WatchdogManager
7204 com.caucho.server.resin.Resin


jps -mlVv localhost
jps [ options ] [ hostid ]
其中,options可以用:
-q (安静)
-m (输出传递给main方法的参数)
-l (显示完整路径)
-v (显示传递给JVM的命令行参数)
-V (显示通过flag文件传递给JVM的参数)
-J (和其他Java工具类似用于传递参数给命令本身要调用的java进程);
hostid是主机id,默认localhost。


======================================
[@zw-90-156 ~]$ jstat -gcutil 1282 2s
S0 S1 E O P YGC YGCT FGC FGCT GCT
0.00 50.00 37.83 11.28 55.71 11 0.026 1 0.056 0.082
0.00 50.00 37.83 11.28 55.71 11 0.026 1 0.056 0.082
0.00 50.00 37.83 11.28 55.71 11 0.026 1 0.056 0.082

可以通过命令:jstat -options option,看到支持的option参数
-class (类加载器)
-compiler (JIT)
-gc (GC堆状态)
-gccapacity (各区大小)
-gccause (最近一次GC统计和原因)
-gcnew (新区统计)
-gcnewcapacity (新区大小)
-gcold (老区统计)
-gcoldcapacity (老区大小)
-gcpermcapacity (永久区大小)
-gcutil (GC统计汇总)
-printcompilation (HotSpot编译统计)

jstat -gcutil pid: 统计gc信息统计。
jstat -gccapacity pid: 可以显示,VM内存中三代(young,old,perm)对象的使用和占用大小

-gccapacity参数:
NGCMN:年轻代(young)中初始化(最小)的大小 (字节)
NGCMX:年轻代(young)的最大容量 (字节)
NGC:年轻代(young)中当前的容量 (字节)
S0C:年轻代中第一个survivor(幸存区)的容量 (字节)
S1C:年轻代中第二个survivor(幸存区)的容量 (字节)
EC:年轻代中Eden(伊甸园)的容量 (字节)
OGCMN:old代中初始化(最小)的大小 (字节)
OGCMX:old代的最大容量 (字节)
OGC:old代当前新生成的容量 (字节)
OC:Old代的容量 (字节)
PGCMN:perm代中初始化(最小)的大小 (字节)
PGCMX:perm代的最大容量 (字节)
PGC:perm代当前新生成的容量 (字节)
PC:Perm(持久代)的容量 (字节)
YGC:从应用程序启动到采样时年轻代中gc次数
FGC:从应用程序启动到采样时old代(全gc)gc次数

=========================================================


[@zw-90-156 ~]$ jstack -l 1282
2014-03-10 10:52:30
Full thread dump Java HotSpot(TM) 64-Bit Server VM (20.14-b01 mixed mode):

"resin-1675" daemon prio=10 tid=0x00002aaabc003000 nid=0x7009 in Object.wait() [0x0000000042834000]
java.lang.Thread.State: TIMED_WAITING (on object monitor)
at java.lang.Object.wait(Native Method)
at com.caucho.util.ThreadPool$Item.runTasks(ThreadPool.java:727)
- locked <0x00000000f674c6d0> (a com.caucho.util.ThreadPool$Item)
at com.caucho.util.ThreadPool$Item.run(ThreadPool.java:662)
at java.lang.Thread.run(Thread.java:662)

Locked ownable synchronizers:
- None

"resin-1674" daemon prio=10 tid=0x00002aaabc006000 nid=0x6b3d in Object.wait() [0x0000000042aff000]
java.lang.Thread.State: TIMED_WAITING (on object monitor)
at java.lang.Object.wait(Native Method)
at com.caucho.util.ThreadPool$Item.runTasks(ThreadPool.java:727)
- locked <0x00000000f674c520> (a com.caucho.util.ThreadPool$Item)
at com.caucho.util.ThreadPool$Item.run(ThreadPool.java:662)
at java.lang.Thread.run(Thread.java:662)

Locked ownable synchronizers:
- None

"resin-1673" daemon prio=10 tid=0x00002aaabc007800 nid=0x5f1f in Object.wait() [0x0000000042b81000]
java.lang.Thread.State: TIMED_WAITING (on object monitor)
at java.lang.Object.wait(Native Method)
at com.caucho.util.ThreadPool$Item.runTasks(ThreadPool.java:727)
- locked <0x00000000f674c370> (a com.caucho.util.ThreadPool$Item)
at com.caucho.util.ThreadPool$Item.run(ThreadPool.java:662)
at java.lang.Thread.run(Thread.java:662)

Locked ownable synchronizers:
- None

"resin-1672" daemon prio=10 tid=0x00002aaabc008000 nid=0x5b0e in Object.wait() [0x0000000042875000]
java.lang.Thread.State: TIMED_WAITING (on object monitor)
at java.lang.Object.wait(Native Method)
at com.caucho.util.ThreadPool$Item.runTasks(ThreadPool.java:727)
- locked <0x00000000f674c1c0> (a com.caucho.util.ThreadPool$Item)
at com.caucho.util.ThreadPool$Item.run(ThreadPool.java:662)
at java.lang.Thread.run(Thread.java:662)

Locked ownable synchronizers:
- None

"resin-1670" daemon prio=10 tid=0x00002aaabc002800 nid=0x38bb in Object.wait() [0x0000000041206000]
java.lang.Thread.State: TIMED_WAITING (on object monitor)
at java.lang.Object.wait(Native Method)
at com.caucho.util.ThreadPool$Item.runTasks(ThreadPool.java:727)
- locked <0x00000000f674be60> (a com.caucho.util.ThreadPool$Item)
at com.caucho.util.ThreadPool$Item.run(ThreadPool.java:662)
at java.lang.Thread.run(Thread.java:662)

Locked ownable synchronizers:
- None

"resin-1669" daemon prio=10 tid=0x00002aaabc001800 nid=0x34a5 in Object.wait() [0x0000000042c44000]
java.lang.Thread.State: TIMED_WAITING (on object monitor)
at java.lang.Object.wait(Native Method)
at com.caucho.util.ThreadPool$Item.runTasks(ThreadPool.java:727)
- locked <0x00000000f674bcb0> (a com.caucho.util.ThreadPool$Item)
at com.caucho.util.ThreadPool$Item.run(ThreadPool.java:662)
at java.lang.Thread.run(Thread.java:662)

Locked ownable synchronizers:
- None

"resin-1662" daemon prio=10 tid=0x00002aaac0007800 nid=0x3369 in Object.wait() [0x0000000042d07000]
java.lang.Thread.State: TIMED_WAITING (on object monitor)
at java.lang.Object.wait(Native Method)
at com.caucho.util.ThreadPool$Item.runTasks(ThreadPool.java:727)
- locked <0x00000000f6263468> (a com.caucho.util.ThreadPool$Item)
at com.caucho.util.ThreadPool$Item.run(ThreadPool.java:662)
at java.lang.Thread.run(Thread.java:662)

Locked ownable synchronizers:
- None

"resin-1657" daemon prio=10 tid=0x0000000041736000 nid=0x5432 in Object.wait() [0x0000000042c03000]
java.lang.Thread.State: TIMED_WAITING (on object monitor)
at java.lang.Object.wait(Native Method)
at com.caucho.util.ThreadPool$Item.runTasks(ThreadPool.java:727)
- locked <0x00000000f6262bf8> (a com.caucho.util.ThreadPool$Item)
at com.caucho.util.ThreadPool$Item.run(ThreadPool.java:662)
at java.lang.Thread.run(Thread.java:662)

Locked ownable synchronizers:
- None

"resin-1656" daemon prio=10 tid=0x0000000041736800 nid=0x4f7b in Object.wait() [0x00000000427f3000]
java.lang.Thread.State: TIMED_WAITING (on object monitor)
at java.lang.Object.wait(Native Method)
at com.caucho.util.ThreadPool$Item.runTasks(ThreadPool.java:727)
- locked <0x00000000f6262a48> (a com.caucho.util.ThreadPool$Item)
at com.caucho.util.ThreadPool$Item.run(ThreadPool.java:662)
at java.lang.Thread.run(Thread.java:662)

Locked ownable synchronizers:
- None

"resin-1653" daemon prio=10 tid=0x0000000041571800 nid=0x6837 in Object.wait() [0x0000000042c85000]
java.lang.Thread.State: TIMED_WAITING (on object monitor)
at java.lang.Object.wait(Native Method)
at com.caucho.util.ThreadPool$Item.runTasks(ThreadPool.java:727)
- locked <0x00000000f6262538> (a com.caucho.util.ThreadPool$Item)
at com.caucho.util.ThreadPool$Item.run(ThreadPool.java:662)
at java.lang.Thread.run(Thread.java:662)

Locked ownable synchronizers:
- None

"Attach Listener" daemon prio=10 tid=0x00002aaab04b7800 nid=0x4357 waiting on condition [0x0000000000000000]
java.lang.Thread.State: RUNNABLE

Locked ownable synchronizers:
- None

"http-127.0.0.1:8087-10$2109028635" daemon prio=10 tid=0x00002aaab04ad800 nid=0x52c waiting for monitor entry [0x0000000042b40000]
java.lang.Thread.State: BLOCKED (on object monitor)
at java.net.PlainSocketImpl.accept(PlainSocketImpl.java:406)
- waiting to lock <0x00000000e100f730> (a java.net.SocksSocketImpl)
at java.net.ServerSocket.implAccept(ServerSocket.java:462)
at java.net.ServerSocket.accept(ServerSocket.java:430)
at com.caucho.vfs.QServerSocketWrapper.accept(QServerSocketWrapper.java:91)
at com.caucho.server.port.Port.accept(Port.java:1179)
at com.caucho.server.port.TcpConnection.run(TcpConnection.java:659)
at com.caucho.util.ThreadPool$Item.runTasks(ThreadPool.java:743)
at com.caucho.util.ThreadPool$Item.run(ThreadPool.java:662)
at java.lang.Thread.run(Thread.java:662)

Locked ownable synchronizers:
- None

"http-127.0.0.1:8087-9$649272183" daemon prio=10 tid=0x00002aaab04b6000 nid=0x529 waiting for monitor entry [0x0000000042abe000]
java.lang.Thread.State: BLOCKED (on object monitor)
at java.net.PlainSocketImpl.accept(PlainSocketImpl.java:406)
- waiting to lock <0x00000000e100f730> (a java.net.SocksSocketImpl)
at java.net.ServerSocket.implAccept(ServerSocket.java:462)
at java.net.ServerSocket.accept(ServerSocket.java:430)
at com.caucho.vfs.QServerSocketWrapper.accept(QServerSocketWrapper.java:91)
at com.caucho.server.port.Port.accept(Port.java:1179)
at com.caucho.server.port.TcpConnection.run(TcpConnection.java:659)
at com.caucho.util.ThreadPool$Item.runTasks(ThreadPool.java:743)
at com.caucho.util.ThreadPool$Item.run(ThreadPool.java:662)
at java.lang.Thread.run(Thread.java:662)

Locked ownable synchronizers:
- None

"http-127.0.0.1:8087-8$458872080" daemon prio=10 tid=0x00002aaab04ba800 nid=0x528 runnable [0x00000000419ef000]
java.lang.Thread.State: RUNNABLE
at java.net.PlainSocketImpl.socketAccept(Native Method)
at java.net.PlainSocketImpl.accept(PlainSocketImpl.java:408)
- locked <0x00000000e100f730> (a java.net.SocksSocketImpl)
at java.net.ServerSocket.implAccept(ServerSocket.java:462)
at java.net.ServerSocket.accept(ServerSocket.java:430)
at com.caucho.vfs.QServerSocketWrapper.accept(QServerSocketWrapper.java:91)
at com.caucho.server.port.Port.accept(Port.java:1179)
at com.caucho.server.port.TcpConnection.run(TcpConnection.java:659)
at com.caucho.util.ThreadPool$Item.runTasks(ThreadPool.java:743)
at com.caucho.util.ThreadPool$Item.run(ThreadPool.java:662)
at java.lang.Thread.run(Thread.java:662)

Locked ownable synchronizers:
- None

"resin-destroy" daemon prio=10 tid=0x00002aaab04b2000 nid=0x526 in Object.wait() [0x00000000411c5000]
java.lang.Thread.State: WAITING (on object monitor)
at java.lang.Object.wait(Native Method)
- waiting on <0x00000000e10e7180> (a com.caucho.server.resin.Resin$DestroyThread)
at java.lang.Object.wait(Object.java:485)
at com.caucho.server.resin.Resin$DestroyThread.run(Resin.java:1779)
- locked <0x00000000e10e7180> (a com.caucho.server.resin.Resin$DestroyThread)

Locked ownable synchronizers:
- None

"resin-port-8087" daemon prio=10 tid=0x00002aaab04a7800 nid=0x525 in Object.wait() [0x00000000404b1000]
java.lang.Thread.State: TIMED_WAITING (on object monitor)
at java.lang.Object.wait(Native Method)
at com.caucho.server.port.Port.run(Port.java:1523)
- locked <0x00000000e05de8c0> (a com.caucho.server.port.Port)
at java.lang.Thread.run(Thread.java:662)

Locked ownable synchronizers:
- None

"resin-port-6907" daemon prio=10 tid=0x00002aaaaf28e800 nid=0x524 in Object.wait() [0x000000004021f000]
java.lang.Thread.State: TIMED_WAITING (on object monitor)
at java.lang.Object.wait(Native Method)
at com.caucho.server.port.Port.run(Port.java:1523)
- locked <0x00000000e05de318> (a com.caucho.server.cluster.ClusterPort)
at java.lang.Thread.run(Thread.java:662)

Locked ownable synchronizers:
- None

"hmux-127.0.0.1:6907-0$2008817593" daemon prio=10 tid=0x00002aaab039d800 nid=0x523 runnable [0x0000000042a7d000]
java.lang.Thread.State: RUNNABLE
at java.net.PlainSocketImpl.socketAccept(Native Method)
at java.net.PlainSocketImpl.accept(PlainSocketImpl.java:408)
- locked <0x00000000e10e7508> (a java.net.SocksSocketImpl)
at java.net.ServerSocket.implAccept(ServerSocket.java:462)
at java.net.ServerSocket.accept(ServerSocket.java:430)
at com.caucho.vfs.QServerSocketWrapper.accept(QServerSocketWrapper.java:91)
at com.caucho.server.port.Port.accept(Port.java:1179)
at com.caucho.server.port.TcpConnection.run(TcpConnection.java:659)
at com.caucho.util.ThreadPool$Item.runTasks(ThreadPool.java:743)
at com.caucho.util.ThreadPool$Item.run(ThreadPool.java:662)
at java.lang.Thread.run(Thread.java:662)

Locked ownable synchronizers:
- None

"hmux-127.0.0.1:6907-2$1606871064" daemon prio=10 tid=0x00002aaab036b000 nid=0x522 waiting for monitor entry [0x0000000042a3c000]
java.lang.Thread.State: BLOCKED (on object monitor)
at java.net.PlainSocketImpl.accept(PlainSocketImpl.java:406)
- waiting to lock <0x00000000e10e7508> (a java.net.SocksSocketImpl)
at java.net.ServerSocket.implAccept(ServerSocket.java:462)
at java.net.ServerSocket.accept(ServerSocket.java:430)
at com.caucho.vfs.QServerSocketWrapper.accept(QServerSocketWrapper.java:91)
at com.caucho.server.port.Port.accept(Port.java:1179)
at com.caucho.server.port.TcpConnection.run(TcpConnection.java:659)
at com.caucho.util.ThreadPool$Item.runTasks(ThreadPool.java:743)
at com.caucho.util.ThreadPool$Item.run(ThreadPool.java:662)
at java.lang.Thread.run(Thread.java:662)

Locked ownable synchronizers:
- None

"http-127.0.0.1:8087-1$2075111623" daemon prio=10 tid=0x00002aaab0527800 nid=0x521 waiting for monitor entry [0x00000000429fb000]
java.lang.Thread.State: BLOCKED (on object monitor)
at java.net.PlainSocketImpl.accept(PlainSocketImpl.java:406)
- waiting to lock <0x00000000e100f730> (a java.net.SocksSocketImpl)
at java.net.ServerSocket.implAccept(ServerSocket.java:462)
at java.net.ServerSocket.accept(ServerSocket.java:430)
at com.caucho.vfs.QServerSocketWrapper.accept(QServerSocketWrapper.java:91)
at com.caucho.server.port.Port.accept(Port.java:1179)
at com.caucho.server.port.TcpConnection.run(TcpConnection.java:659)
at com.caucho.util.ThreadPool$Item.runTasks(ThreadPool.java:743)
at com.caucho.util.ThreadPool$Item.run(ThreadPool.java:662)
at java.lang.Thread.run(Thread.java:662)

Locked ownable synchronizers:
- None

"http-127.0.0.1:8087-3$1266620481" daemon prio=10 tid=0x00002aaab028a800 nid=0x520 waiting for monitor entry [0x00000000429ba000]
java.lang.Thread.State: BLOCKED (on object monitor)
at java.net.PlainSocketImpl.accept(PlainSocketImpl.java:406)
- waiting to lock <0x00000000e100f730> (a java.net.SocksSocketImpl)
at java.net.ServerSocket.implAccept(ServerSocket.java:462)
at java.net.ServerSocket.accept(ServerSocket.java:430)
at com.caucho.vfs.QServerSocketWrapper.accept(QServerSocketWrapper.java:91)
at com.caucho.server.port.Port.accept(Port.java:1179)
at com.caucho.server.port.TcpConnection.run(TcpConnection.java:659)
at com.caucho.util.ThreadPool$Item.runTasks(ThreadPool.java:743)
at com.caucho.util.ThreadPool$Item.run(ThreadPool.java:662)
at java.lang.Thread.run(Thread.java:662)

Locked ownable synchronizers:
- None

"hmux-127.0.0.1:6907-4$85031456" daemon prio=10 tid=0x00002aaab04e1000 nid=0x51f waiting for monitor entry [0x0000000042979000]
java.lang.Thread.State: BLOCKED (on object monitor)
at java.net.PlainSocketImpl.accept(PlainSocketImpl.java:406)
- waiting to lock <0x00000000e10e7508> (a java.net.SocksSocketImpl)
at java.net.ServerSocket.implAccept(ServerSocket.java:462)
at java.net.ServerSocket.accept(ServerSocket.java:430)
at com.caucho.vfs.QServerSocketWrapper.accept(QServerSocketWrapper.java:91)
at com.caucho.server.port.Port.accept(Port.java:1179)
at com.caucho.server.port.TcpConnection.run(TcpConnection.java:659)
at com.caucho.util.ThreadPool$Item.runTasks(ThreadPool.java:743)
at com.caucho.util.ThreadPool$Item.run(ThreadPool.java:662)
at java.lang.Thread.run(Thread.java:662)

Locked ownable synchronizers:
- None

"http-127.0.0.1:8087-5$1047055737" daemon prio=10 tid=0x00002aaab048d000 nid=0x51e waiting for monitor entry [0x0000000042938000]
java.lang.Thread.State: BLOCKED (on object monitor)
at java.net.PlainSocketImpl.accept(PlainSocketImpl.java:406)
- waiting to lock <0x00000000e100f730> (a java.net.SocksSocketImpl)
at java.net.ServerSocket.implAccept(ServerSocket.java:462)
at java.net.ServerSocket.accept(ServerSocket.java:430)
at com.caucho.vfs.QServerSocketWrapper.accept(QServerSocketWrapper.java:91)
at com.caucho.server.port.Port.accept(Port.java:1179)
at com.caucho.server.port.TcpConnection.run(TcpConnection.java:659)
at com.caucho.util.ThreadPool$Item.runTasks(ThreadPool.java:743)
at com.caucho.util.ThreadPool$Item.run(ThreadPool.java:662)
at java.lang.Thread.run(Thread.java:662)

Locked ownable synchronizers:
- None

"hmux-127.0.0.1:6907-6$1384768241" daemon prio=10 tid=0x00002aaaaf2a5000 nid=0x51d waiting for monitor entry [0x00000000428f7000]
java.lang.Thread.State: BLOCKED (on object monitor)
at java.net.PlainSocketImpl.accept(PlainSocketImpl.java:406)
- waiting to lock <0x00000000e10e7508> (a java.net.SocksSocketImpl)
at java.net.ServerSocket.implAccept(ServerSocket.java:462)
at java.net.ServerSocket.accept(ServerSocket.java:430)
at com.caucho.vfs.QServerSocketWrapper.accept(QServerSocketWrapper.java:91)
at com.caucho.server.port.Port.accept(Port.java:1179)
at com.caucho.server.port.TcpConnection.run(TcpConnection.java:659)
at com.caucho.util.ThreadPool$Item.runTasks(ThreadPool.java:743)
at com.caucho.util.ThreadPool$Item.run(ThreadPool.java:662)
at java.lang.Thread.run(Thread.java:662)

Locked ownable synchronizers:
- None

"hmux-127.0.0.1:6907-7$1519543948" daemon prio=10 tid=0x0000000041801000 nid=0x51c waiting for monitor entry [0x00000000428b6000]
java.lang.Thread.State: BLOCKED (on object monitor)
at java.net.PlainSocketImpl.accept(PlainSocketImpl.java:406)
- waiting to lock <0x00000000e10e7508> (a java.net.SocksSocketImpl)
at java.net.ServerSocket.implAccept(ServerSocket.java:462)
at java.net.ServerSocket.accept(ServerSocket.java:430)
at com.caucho.vfs.QServerSocketWrapper.accept(QServerSocketWrapper.java:91)
at com.caucho.server.port.Port.accept(Port.java:1179)
at com.caucho.server.port.TcpConnection.run(TcpConnection.java:659)
at com.caucho.util.ThreadPool$Item.runTasks(ThreadPool.java:743)
at com.caucho.util.ThreadPool$Item.run(ThreadPool.java:662)
at java.lang.Thread.run(Thread.java:662)

Locked ownable synchronizers:
- None

"resin-alarm" daemon prio=10 tid=0x00002aaab04e8800 nid=0x518 waiting on condition [0x0000000041bb8000]
java.lang.Thread.State: TIMED_WAITING (sleeping)
at java.lang.Thread.sleep(Native Method)
at com.caucho.util.Alarm$AlarmThread.run(Alarm.java:586)

Locked ownable synchronizers:
- None

"resin-thread-scheduler" daemon prio=10 tid=0x00002aaab0244800 nid=0x515 in Object.wait() [0x000000004114b000]
java.lang.Thread.State: TIMED_WAITING (on object monitor)
at java.lang.Object.wait(Native Method)
at com.caucho.util.ThreadPool$ScheduleThread.run(ThreadPool.java:925)
- locked <0x00000000e05b6b90> (a java.util.ArrayList)
at java.lang.Thread.run(Thread.java:662)

Locked ownable synchronizers:
- None

"resin-thread-launcher" daemon prio=10 tid=0x00002aaab021f000 nid=0x514 in Object.wait() [0x00000000402cd000]
java.lang.Thread.State: TIMED_WAITING (on object monitor)
at java.lang.Object.wait(Native Method)
at com.caucho.util.ThreadPool$ThreadLauncher.startConnection(ThreadPool.java:858)
- locked <0x00000000e05b6c30> (a com.caucho.util.ThreadPool$ThreadLauncher)
at com.caucho.util.ThreadPool$ThreadLauncher.run(ThreadPool.java:881)
at java.lang.Thread.run(Thread.java:662)

Locked ownable synchronizers:
- None

"Low Memory Detector" daemon prio=10 tid=0x00000000415f1800 nid=0x512 runnable [0x0000000000000000]
java.lang.Thread.State: RUNNABLE

Locked ownable synchronizers:
- None

"C2 CompilerThread1" daemon prio=10 tid=0x000000004160d000 nid=0x511 waiting on condition [0x0000000000000000]
java.lang.Thread.State: RUNNABLE

Locked ownable synchronizers:
- None

"C2 CompilerThread0" daemon prio=10 tid=0x00000000415f6000 nid=0x510 waiting on condition [0x0000000000000000]
java.lang.Thread.State: RUNNABLE

Locked ownable synchronizers:
- None

"Signal Dispatcher" daemon prio=10 tid=0x00000000415ea800 nid=0x50f runnable [0x0000000000000000]
java.lang.Thread.State: RUNNABLE

Locked ownable synchronizers:
- None

"Finalizer" daemon prio=10 tid=0x00000000415a7000 nid=0x50e in Object.wait() [0x000000004246e000]
java.lang.Thread.State: WAITING (on object monitor)
at java.lang.Object.wait(Native Method)
at java.lang.ref.ReferenceQueue.remove(ReferenceQueue.java:118)
- locked <0x00000000e05b7310> (a java.lang.ref.ReferenceQueue$Lock)
at java.lang.ref.ReferenceQueue.remove(ReferenceQueue.java:134)
at java.lang.ref.Finalizer$FinalizerThread.run(Finalizer.java:159)

Locked ownable synchronizers:
- None

"Reference Handler" daemon prio=10 tid=0x000000004159f800 nid=0x50d in Object.wait() [0x000000004242d000]
java.lang.Thread.State: WAITING (on object monitor)
at java.lang.Object.wait(Native Method)
at java.lang.Object.wait(Object.java:485)
at java.lang.ref.Reference$ReferenceHandler.run(Reference.java:116)
- locked <0x00000000e05b7408> (a java.lang.ref.Reference$Lock)

Locked ownable synchronizers:
- None

"main" prio=10 tid=0x0000000041533000 nid=0x503 runnable [0x000000004027d000]
java.lang.Thread.State: RUNNABLE
at java.net.SocketInputStream.socketRead0(Native Method)
at java.net.SocketInputStream.read(SocketInputStream.java:129)
at java.net.SocketInputStream.read(SocketInputStream.java:182)
at com.caucho.server.resin.Resin.waitForExit(Resin.java:1270)
at com.caucho.server.resin.Resin.main(Resin.java:1372)

Locked ownable synchronizers:
- None

"VM Thread" prio=10 tid=0x0000000041599000 nid=0x50c runnable

"GC task thread#0 (ParallelGC)" prio=10 tid=0x0000000041546000 nid=0x504 runnable

"GC task thread#1 (ParallelGC)" prio=10 tid=0x0000000041548000 nid=0x505 runnable

"GC task thread#2 (ParallelGC)" prio=10 tid=0x000000004154a000 nid=0x506 runnable

"GC task thread#3 (ParallelGC)" prio=10 tid=0x000000004154b800 nid=0x507 runnable

"GC task thread#4 (ParallelGC)" prio=10 tid=0x000000004154d800 nid=0x508 runnable

"GC task thread#5 (ParallelGC)" prio=10 tid=0x000000004154f800 nid=0x509 runnable

"GC task thread#6 (ParallelGC)" prio=10 tid=0x0000000041551000 nid=0x50a runnable

"GC task thread#7 (ParallelGC)" prio=10 tid=0x0000000041553000 nid=0x50b runnable

"VM Periodic Task Thread" prio=10 tid=0x00000000415f4000 nid=0x513 waiting on condition

JNI global references: 1424

========================================================
[@zw-90-156 ~]$ jstack -F 1282
Attaching to process ID 1282, please wait...
Debugger attached successfully.
Server compiler detected.
JVM version is 20.14-b01
Deadlock Detection:

No deadlocks found.

Thread 1152: (state = BLOCKED)
- java.lang.Object.wait(long) @bci=0 (Compiled frame; information may be imprecise)
- com.caucho.util.ThreadPool$Item.runTasks() @bci=224, line=727 (Compiled frame)
- com.caucho.util.ThreadPool$Item.run() @bci=106, line=662 (Interpreted frame)
- java.lang.Thread.run() @bci=11, line=662 (Interpreted frame)


Thread 28681: (state = BLOCKED)
- java.lang.Object.wait(long) @bci=0 (Compiled frame; information may be imprecise)
- com.caucho.util.ThreadPool$Item.runTasks() @bci=224, line=727 (Compiled frame)
- com.caucho.util.ThreadPool$Item.run() @bci=106, line=662 (Interpreted frame)
- java.lang.Thread.run() @bci=11, line=662 (Interpreted frame)


Thread 27453: (state = BLOCKED)
- java.lang.Object.wait(long) @bci=0 (Compiled frame; information may be imprecise)
- com.caucho.util.ThreadPool$Item.runTasks() @bci=224, line=727 (Compiled frame)
- com.caucho.util.ThreadPool$Item.run() @bci=106, line=662 (Interpreted frame)
- java.lang.Thread.run() @bci=11, line=662 (Interpreted frame)


Thread 24351: (state = BLOCKED)
- java.lang.Object.wait(long) @bci=0 (Compiled frame; information may be imprecise)
- com.caucho.util.ThreadPool$Item.runTasks() @bci=224, line=727 (Compiled frame)
- com.caucho.util.ThreadPool$Item.run() @bci=106, line=662 (Interpreted frame)
- java.lang.Thread.run() @bci=11, line=662 (Interpreted frame)


Thread 23310: (state = BLOCKED)
- java.lang.Object.wait(long) @bci=0 (Compiled frame; information may be imprecise)
- com.caucho.util.ThreadPool$Item.runTasks() @bci=224, line=727 (Compiled frame)
- com.caucho.util.ThreadPool$Item.run() @bci=106, line=662 (Interpreted frame)
- java.lang.Thread.run() @bci=11, line=662 (Interpreted frame)


Thread 14523: (state = BLOCKED)
- java.lang.Object.wait(long) @bci=0 (Compiled frame; information may be imprecise)
- com.caucho.util.ThreadPool$Item.runTasks() @bci=224, line=727 (Compiled frame)
- com.caucho.util.ThreadPool$Item.run() @bci=106, line=662 (Interpreted frame)
- java.lang.Thread.run() @bci=11, line=662 (Interpreted frame)


Thread 13477: (state = BLOCKED)
- java.lang.Object.wait(long) @bci=0 (Compiled frame; information may be imprecise)
- com.caucho.util.ThreadPool$Item.runTasks() @bci=224, line=727 (Compiled frame)
- com.caucho.util.ThreadPool$Item.run() @bci=106, line=662 (Interpreted frame)
- java.lang.Thread.run() @bci=11, line=662 (Interpreted frame)


Thread 13161: (state = BLOCKED)
- java.lang.Object.wait(long) @bci=0 (Compiled frame; information may be imprecise)
- com.caucho.util.ThreadPool$Item.runTasks() @bci=224, line=727 (Compiled frame)
- com.caucho.util.ThreadPool$Item.run() @bci=106, line=662 (Interpreted frame)
- java.lang.Thread.run() @bci=11, line=662 (Interpreted frame)


Thread 21554: (state = BLOCKED)
- java.lang.Object.wait(long) @bci=0 (Compiled frame; information may be imprecise)
- com.caucho.util.ThreadPool$Item.runTasks() @bci=224, line=727 (Compiled frame)
- com.caucho.util.ThreadPool$Item.run() @bci=106, line=662 (Interpreted frame)
- java.lang.Thread.run() @bci=11, line=662 (Interpreted frame)


Thread 20347: (state = BLOCKED)
- java.lang.Object.wait(long) @bci=0 (Compiled frame; information may be imprecise)
- com.caucho.util.ThreadPool$Item.runTasks() @bci=224, line=727 (Compiled frame)
- com.caucho.util.ThreadPool$Item.run() @bci=106, line=662 (Interpreted frame)
- java.lang.Thread.run() @bci=11, line=662 (Interpreted frame)


Thread 26679: (state = BLOCKED)
- java.lang.Object.wait(long) @bci=0 (Compiled frame; information may be imprecise)
- com.caucho.util.ThreadPool$Item.runTasks() @bci=224, line=727 (Compiled frame)
- com.caucho.util.ThreadPool$Item.run() @bci=106, line=662 (Interpreted frame)
- java.lang.Thread.run() @bci=11, line=662 (Interpreted frame)


Thread 17239: (state = BLOCKED)


Thread 1324: (state = BLOCKED)
- java.net.PlainSocketImpl.accept(java.net.SocketImpl) @bci=0, line=406 (Interpreted frame)
- java.net.ServerSocket.implAccept(java.net.Socket) @bci=60, line=462 (Interpreted frame)
- java.net.ServerSocket.accept() @bci=48, line=430 (Interpreted frame)
- com.caucho.vfs.QServerSocketWrapper.accept(com.caucho.vfs.QSocket) @bci=9, line=91 (Interpreted frame)
- com.caucho.server.port.Port.accept(com.caucho.server.port.TcpConnection, boolean) @bci=142, line=1179 (Interpreted frame)
- com.caucho.server.port.TcpConnection.run() @bci=328, line=659 (Interpreted frame)
- com.caucho.util.ThreadPool$Item.runTasks() @bci=278, line=743 (Interpreted frame)
- com.caucho.util.ThreadPool$Item.run() @bci=106, line=662 (Interpreted frame)
- java.lang.Thread.run() @bci=11, line=662 (Interpreted frame)


Thread 1321: (state = BLOCKED)
- java.net.PlainSocketImpl.accept(java.net.SocketImpl) @bci=0, line=406 (Interpreted frame)
- java.net.ServerSocket.implAccept(java.net.Socket) @bci=60, line=462 (Interpreted frame)
- java.net.ServerSocket.accept() @bci=48, line=430 (Interpreted frame)
- com.caucho.vfs.QServerSocketWrapper.accept(com.caucho.vfs.QSocket) @bci=9, line=91 (Interpreted frame)
- com.caucho.server.port.Port.accept(com.caucho.server.port.TcpConnection, boolean) @bci=142, line=1179 (Interpreted frame)
- com.caucho.server.port.TcpConnection.run() @bci=328, line=659 (Interpreted frame)
- com.caucho.util.ThreadPool$Item.runTasks() @bci=278, line=743 (Interpreted frame)
- com.caucho.util.ThreadPool$Item.run() @bci=106, line=662 (Interpreted frame)
- java.lang.Thread.run() @bci=11, line=662 (Interpreted frame)


Thread 1320: (state = IN_NATIVE)
- java.net.PlainSocketImpl.socketAccept(java.net.SocketImpl) @bci=0 (Interpreted frame)
- java.net.PlainSocketImpl.accept(java.net.SocketImpl) @bci=7, line=408 (Interpreted frame)
- java.net.ServerSocket.implAccept(java.net.Socket) @bci=60, line=462 (Interpreted frame)
- java.net.ServerSocket.accept() @bci=48, line=430 (Interpreted frame)
- com.caucho.vfs.QServerSocketWrapper.accept(com.caucho.vfs.QSocket) @bci=9, line=91 (Interpreted frame)
- com.caucho.server.port.Port.accept(com.caucho.server.port.TcpConnection, boolean) @bci=142, line=1179 (Interpreted frame)
- com.caucho.server.port.TcpConnection.run() @bci=328, line=659 (Interpreted frame)
- com.caucho.util.ThreadPool$Item.runTasks() @bci=278, line=743 (Interpreted frame)
- com.caucho.util.ThreadPool$Item.run() @bci=106, line=662 (Interpreted frame)
- java.lang.Thread.run() @bci=11, line=662 (Interpreted frame)


Thread 1318: (state = BLOCKED)
- java.lang.Object.wait(long) @bci=0 (Interpreted frame)
- java.lang.Object.wait() @bci=2, line=485 (Interpreted frame)
- com.caucho.server.resin.Resin$DestroyThread.run() @bci=12, line=1779 (Interpreted frame)


Thread 1317: (state = BLOCKED)
- java.lang.Object.wait(long) @bci=0 (Compiled frame; information may be imprecise)
- com.caucho.server.port.Port.run() @bci=85, line=1523 (Compiled frame)
- java.lang.Thread.run() @bci=11, line=662 (Interpreted frame)


Thread 1316: (state = BLOCKED)
- java.lang.Object.wait(long) @bci=0 (Compiled frame; information may be imprecise)
- com.caucho.server.port.Port.run() @bci=85, line=1523 (Compiled frame)
- java.lang.Thread.run() @bci=11, line=662 (Interpreted frame)


Thread 1315: (state = IN_NATIVE)
- java.net.PlainSocketImpl.socketAccept(java.net.SocketImpl) @bci=0 (Interpreted frame)
- java.net.PlainSocketImpl.accept(java.net.SocketImpl) @bci=7, line=408 (Interpreted frame)
- java.net.ServerSocket.implAccept(java.net.Socket) @bci=60, line=462 (Interpreted frame)
- java.net.ServerSocket.accept() @bci=48, line=430 (Interpreted frame)
- com.caucho.vfs.QServerSocketWrapper.accept(com.caucho.vfs.QSocket) @bci=9, line=91 (Interpreted frame)
- com.caucho.server.port.Port.accept(com.caucho.server.port.TcpConnection, boolean) @bci=142, line=1179 (Interpreted frame)
- com.caucho.server.port.TcpConnection.run() @bci=328, line=659 (Interpreted frame)
- com.caucho.util.ThreadPool$Item.runTasks() @bci=278, line=743 (Interpreted frame)
- com.caucho.util.ThreadPool$Item.run() @bci=106, line=662 (Interpreted frame)
- java.lang.Thread.run() @bci=11, line=662 (Interpreted frame)


Thread 1314: (state = BLOCKED)
- java.net.PlainSocketImpl.accept(java.net.SocketImpl) @bci=0, line=406 (Interpreted frame)
- java.net.ServerSocket.implAccept(java.net.Socket) @bci=60, line=462 (Interpreted frame)
- java.net.ServerSocket.accept() @bci=48, line=430 (Interpreted frame)
- com.caucho.vfs.QServerSocketWrapper.accept(com.caucho.vfs.QSocket) @bci=9, line=91 (Interpreted frame)
- com.caucho.server.port.Port.accept(com.caucho.server.port.TcpConnection, boolean) @bci=142, line=1179 (Interpreted frame)
- com.caucho.server.port.TcpConnection.run() @bci=328, line=659 (Interpreted frame)
- com.caucho.util.ThreadPool$Item.runTasks() @bci=278, line=743 (Interpreted frame)
- com.caucho.util.ThreadPool$Item.run() @bci=106, line=662 (Interpreted frame)
- java.lang.Thread.run() @bci=11, line=662 (Interpreted frame)


Thread 1313: (state = BLOCKED)
- java.net.PlainSocketImpl.accept(java.net.SocketImpl) @bci=0, line=406 (Interpreted frame)
- java.net.ServerSocket.implAccept(java.net.Socket) @bci=60, line=462 (Interpreted frame)
- java.net.ServerSocket.accept() @bci=48, line=430 (Interpreted frame)
- com.caucho.vfs.QServerSocketWrapper.accept(com.caucho.vfs.QSocket) @bci=9, line=91 (Interpreted frame)
- com.caucho.server.port.Port.accept(com.caucho.server.port.TcpConnection, boolean) @bci=142, line=1179 (Interpreted frame)
- com.caucho.server.port.TcpConnection.run() @bci=328, line=659 (Interpreted frame)
- com.caucho.util.ThreadPool$Item.runTasks() @bci=278, line=743 (Interpreted frame)
- com.caucho.util.ThreadPool$Item.run() @bci=106, line=662 (Interpreted frame)
- java.lang.Thread.run() @bci=11, line=662 (Interpreted frame)


Thread 1312: (state = BLOCKED)
- java.net.PlainSocketImpl.accept(java.net.SocketImpl) @bci=0, line=406 (Interpreted frame)
- java.net.ServerSocket.implAccept(java.net.Socket) @bci=60, line=462 (Interpreted frame)
- java.net.ServerSocket.accept() @bci=48, line=430 (Interpreted frame)
- com.caucho.vfs.QServerSocketWrapper.accept(com.caucho.vfs.QSocket) @bci=9, line=91 (Interpreted frame)
- com.caucho.server.port.Port.accept(com.caucho.server.port.TcpConnection, boolean) @bci=142, line=1179 (Interpreted frame)
- com.caucho.server.port.TcpConnection.run() @bci=328, line=659 (Interpreted frame)
- com.caucho.util.ThreadPool$Item.runTasks() @bci=278, line=743 (Interpreted frame)
- com.caucho.util.ThreadPool$Item.run() @bci=106, line=662 (Interpreted frame)
- java.lang.Thread.run() @bci=11, line=662 (Interpreted frame)


Thread 1311: (state = BLOCKED)
- java.net.PlainSocketImpl.accept(java.net.SocketImpl) @bci=0, line=406 (Interpreted frame)
- java.net.ServerSocket.implAccept(java.net.Socket) @bci=60, line=462 (Interpreted frame)
- java.net.ServerSocket.accept() @bci=48, line=430 (Interpreted frame)
- com.caucho.vfs.QServerSocketWrapper.accept(com.caucho.vfs.QSocket) @bci=9, line=91 (Interpreted frame)
- com.caucho.server.port.Port.accept(com.caucho.server.port.TcpConnection, boolean) @bci=142, line=1179 (Interpreted frame)
- com.caucho.server.port.TcpConnection.run() @bci=328, line=659 (Interpreted frame)
- com.caucho.util.ThreadPool$Item.runTasks() @bci=278, line=743 (Interpreted frame)
- com.caucho.util.ThreadPool$Item.run() @bci=106, line=662 (Interpreted frame)
- java.lang.Thread.run() @bci=11, line=662 (Interpreted frame)


Thread 1310: (state = BLOCKED)
- java.net.PlainSocketImpl.accept(java.net.SocketImpl) @bci=0, line=406 (Interpreted frame)
- java.net.ServerSocket.implAccept(java.net.Socket) @bci=60, line=462 (Interpreted frame)
- java.net.ServerSocket.accept() @bci=48, line=430 (Interpreted frame)
- com.caucho.vfs.QServerSocketWrapper.accept(com.caucho.vfs.QSocket) @bci=9, line=91 (Interpreted frame)
- com.caucho.server.port.Port.accept(com.caucho.server.port.TcpConnection, boolean) @bci=142, line=1179 (Interpreted frame)
- com.caucho.server.port.TcpConnection.run() @bci=328, line=659 (Interpreted frame)
- com.caucho.util.ThreadPool$Item.runTasks() @bci=278, line=743 (Interpreted frame)
- com.caucho.util.ThreadPool$Item.run() @bci=106, line=662 (Interpreted frame)
- java.lang.Thread.run() @bci=11, line=662 (Interpreted frame)


Thread 1309: (state = BLOCKED)
- java.net.PlainSocketImpl.accept(java.net.SocketImpl) @bci=0, line=406 (Interpreted frame)
- java.net.ServerSocket.implAccept(java.net.Socket) @bci=60, line=462 (Interpreted frame)
- java.net.ServerSocket.accept() @bci=48, line=430 (Interpreted frame)
- com.caucho.vfs.QServerSocketWrapper.accept(com.caucho.vfs.QSocket) @bci=9, line=91 (Interpreted frame)
- com.caucho.server.port.Port.accept(com.caucho.server.port.TcpConnection, boolean) @bci=142, line=1179 (Interpreted frame)
- com.caucho.server.port.TcpConnection.run() @bci=328, line=659 (Interpreted frame)
- com.caucho.util.ThreadPool$Item.runTasks() @bci=278, line=743 (Interpreted frame)
- com.caucho.util.ThreadPool$Item.run() @bci=106, line=662 (Interpreted frame)
- java.lang.Thread.run() @bci=11, line=662 (Interpreted frame)


Thread 1308: (state = BLOCKED)
- java.net.PlainSocketImpl.accept(java.net.SocketImpl) @bci=0, line=406 (Interpreted frame)
- java.net.ServerSocket.implAccept(java.net.Socket) @bci=60, line=462 (Interpreted frame)
- java.net.ServerSocket.accept() @bci=48, line=430 (Interpreted frame)
- com.caucho.vfs.QServerSocketWrapper.accept(com.caucho.vfs.QSocket) @bci=9, line=91 (Interpreted frame)
- com.caucho.server.port.Port.accept(com.caucho.server.port.TcpConnection, boolean) @bci=142, line=1179 (Interpreted frame)
- com.caucho.server.port.TcpConnection.run() @bci=328, line=659 (Interpreted frame)
- com.caucho.util.ThreadPool$Item.runTasks() @bci=278, line=743 (Interpreted frame)
- com.caucho.util.ThreadPool$Item.run() @bci=106, line=662 (Interpreted frame)
- java.lang.Thread.run() @bci=11, line=662 (Interpreted frame)


Thread 1304: (state = BLOCKED)
- java.lang.Thread.sleep(long) @bci=0 (Compiled frame; information may be imprecise)
- com.caucho.util.Alarm$AlarmThread.run() @bci=35, line=586 (Compiled frame)


Thread 1301: (state = BLOCKED)
- java.lang.Object.wait(long) @bci=0 (Compiled frame; information may be imprecise)
- com.caucho.util.ThreadPool$ScheduleThread.run() @bci=90, line=925 (Interpreted frame)
- java.lang.Thread.run() @bci=11, line=662 (Interpreted frame)


Thread 1300: (state = BLOCKED)
- java.lang.Object.wait(long) @bci=0 (Compiled frame; information may be imprecise)
- com.caucho.util.ThreadPool$ThreadLauncher.startConnection(long) @bci=214, line=858 (Compiled frame)
- com.caucho.util.ThreadPool$ThreadLauncher.run() @bci=48, line=881 (Compiled frame)
- java.lang.Thread.run() @bci=11, line=662 (Interpreted frame)


Thread 1295: (state = BLOCKED)


Thread 1294: (state = BLOCKED)
- java.lang.Object.wait(long) @bci=0 (Compiled frame; information may be imprecise)
- java.lang.ref.ReferenceQueue.remove(long) @bci=44, line=118 (Interpreted frame)
- java.lang.ref.ReferenceQueue.remove() @bci=2, line=134 (Interpreted frame)
- java.lang.ref.Finalizer$FinalizerThread.run() @bci=3, line=159 (Interpreted frame)


Thread 1293: (state = BLOCKED)
- java.lang.Object.wait(long) @bci=0 (Compiled frame; information may be imprecise)
- java.lang.Object.wait() @bci=2, line=485 (Interpreted frame)
- java.lang.ref.Reference$ReferenceHandler.run() @bci=46, line=116 (Interpreted frame)


Thread 1283: (state = IN_NATIVE)
- java.net.SocketInputStream.socketRead0(java.io.FileDescriptor, byte[], int, int, int) @bci=0 (Interpreted frame)
- java.net.SocketInputStream.read(byte[], int, int) @bci=84, line=129 (Interpreted frame)
- java.net.SocketInputStream.read() @bci=23, line=182 (Interpreted frame)
- com.caucho.server.resin.Resin.waitForExit() @bci=304, line=1270 (Interpreted frame)
- com.caucho.server.resin.Resin.main(java.lang.String[]) @bci=42, line=1372 (Interpreted frame)

=============================================================
jmap:显示java进程内存使用的相关信息
jmap pid #打印内存使用的摘要信息
jmap –heap pid #java heap信息
jmap -histo:live pid #统计对象count ,live表示在使用
jmap -histo pid >mem.txt #打印比较简单的各个有多少个对象占了多少内存的信息,一般重定向的文件
jmap -dump:format=b,file=mem.dat pid #将内存使用的详细情况输出到mem.dat 文件

jvm配置打印GC相关信息
-XX:+PrintGCDetails -XX:+PrintGCTimeStamps -XX:+PrintHeapAtGC
对应的日志会输出到catalina的日志中去

jinfo -flag HeapDumpBeforeFullGC 29167 #查看HeapDumpBeforeFullGC
jinfo: 查看和修改JVM参数
Usage:
jinfo <option> <pid>
(to connect to a running process)

where <option> is one of:
-flag <name> to print the value of the named VM flag
-flag [+|-]<name> to enable or disable the named VM flag
-flag <name>=<value> to set the named VM flag to the given value
-h | -help to print this help message


[@zw-90-156 ~]$ jmap 1282
Attaching to process ID 1282, please wait...
Debugger attached successfully.
Server compiler detected.
JVM version is 20.14-b01
0x0000000040000000 49K /opt/jdk1.6.0_43/bin/java
0x00000037a5600000 140K /lib64/ld-2.5.so
0x00000037a5a00000 1681K /lib64/libc-2.5.so
0x00000037a5e00000 22K /lib64/libdl-2.5.so
0x00000037a6200000 600K /lib64/libm-2.5.so
0x00000037a6600000 142K /lib64/libpthread-2.5.so
0x00000037a6e00000 52K /lib64/librt-2.5.so
0x00000037aa600000 111K /lib64/libnsl-2.5.so
0x00002aaaaaac3000 64K /opt/jdk1.6.0_43/jre/lib/amd64/libverify.so
0x00002aaaaabd2000 229K /opt/jdk1.6.0_43/jre/lib/amd64/libjava.so
0x00002aaaaad1a000 52K /lib64/libnss_files-2.5.so
0x00002aaaaaf25000 90K /opt/jdk1.6.0_43/jre/lib/amd64/libzip.so
0x00002aaaaf3d2000 38K /opt/jdk1.6.0_43/jre/lib/amd64/libmanagement.so
0x00002aaaaf4d9000 110K /opt/jdk1.6.0_43/jre/lib/amd64/libnet.so
0x00002ad21d600000 47K /opt/jdk1.6.0_43/jre/lib/amd64/jli/libjli.so
0x00002ad21d70d000 13050K /opt/jdk1.6.0_43/jre/lib/amd64/server/libjvm.so

==============================================


[@zw-90-156 ~]$ jmap -heap 1282
Attaching to process ID 1282, please wait...
Debugger attached successfully.
Server compiler detected.
JVM version is 20.14-b01

using thread-local object allocation.
Parallel GC with 8 thread(s)

Heap Configuration:
MinHeapFreeRatio = 40
MaxHeapFreeRatio = 70
MaxHeapSize = 536870912 (512.0MB)
NewSize = 1310720 (1.25MB)
MaxNewSize = 17592186044415 MB
OldSize = 5439488 (5.1875MB)
NewRatio = 2
SurvivorRatio = 8
PermSize = 21757952 (20.75MB)
MaxPermSize = 268435456 (256.0MB)

Heap Usage:
PS Young Generation
Eden Space:
capacity = 53477376 (51.0MB)
used = 20790384 (19.827255249023438MB)
free = 32686992 (31.172744750976562MB)
38.87697107651655% used
From Space:
capacity = 65536 (0.0625MB)
used = 32768 (0.03125MB)
free = 32768 (0.03125MB)
50.0% used
To Space:
capacity = 14483456 (13.8125MB)
used = 0 (0.0MB)
free = 14483456 (13.8125MB)
0.0% used
PS Old Generation
capacity = 174915584 (166.8125MB)
used = 19734216 (18.82001495361328MB)
free = 155181368 (147.99248504638672MB)
11.28213710220354% used
PS Perm Generation
capacity = 28114944 (26.8125MB)
used = 15663608 (14.937980651855469MB)
free = 12451336 (11.874519348144531MB)
55.71274835190851% used

=======================================================

java虽然是自动回收内存,但是应用程序,尤其服务器程序最好根据业务情况指明内存分配限制。否则可能导致应用程序宕掉。

举例说明含义:
-Xms128m
表示JVM Heap(堆内存)最小尺寸128MB,初始分配
-Xmx512m
表示JVM Heap(堆内存)最大允许的尺寸256MB,按需分配。

说明:如果-Xmx不指定或者指定偏小,应用可能会导致java.lang.OutOfMemory错误,此错误来自JVM不是Throwable的,无法用try...catch捕捉。

PermSize和MaxPermSize指明虚拟机为java永久生成对象(Permanate generation)如,class对象、方法对象这些可反射(reflective)对象分配内存限制,这些内存不包括在Heap(堆内存)区之中。

-XX:PermSize=64MB 最小尺寸,初始分配
-XX:MaxPermSize=256MB 最大允许分配尺寸,按需分配
过小会导致:java.lang.OutOfMemoryError: PermGen space

MaxPermSize缺省值和-server -client选项相关。
-server选项下默认MaxPermSize为64m
-client选项下默认MaxPermSize为32m


经验:
1、慎用最小限制选项Xms,PermSize已节约系统资源。

=========================================================

近期研究对jvm的内存使用情况进行监控,因此对观察虚拟机的内存使用方法做了一些收集,对jvm的参数设置了解了一下:

几个基本概念:

PermGen space:全称是Permanent Generation space,即永久代。就是说是永久保存的区域,用于存放Class和Meta信息,Class在被Load的时候被放入该区域,GC(Garbage Collection)应该不会对PermGen space进行清理,所以如果你的APP会LOAD很多CLASS的话,就很可能出现PermGen space错误。
Heap space:存放Instance。Java Heap分为3个区,Young即新生代,Old即老生代和Permanent。Young保存刚实例化的对象。当该区被填满时,GC会将对象移到Old区。Permanent区则负责保存反射对象。

几个参数设置的意义:

xms/xmx:定义YOUNG+OLD段的总尺寸,ms为JVM启动时YOUNG+OLD的内存大小;mx为最大可占用的YOUNG+OLD内存大小。在用户生产环境上一般将这两个值设为相同,以减少运行期间系统在内存申请上所花的开销。
NewSize/MaxNewSize:定义YOUNG段的尺寸,NewSize为JVM启动时YOUNG的内存大小;MaxNewSize为最大可占用的YOUNG内存大小。在用户生产环境上一般将这两个值设为相同,以减少运行期间系统在内存申请上所花的开销。
PermSize/MaxPermSize:定义Perm段的尺寸,PermSize为JVM启动时Perm的内存大小;MaxPermSize为最大可占用的Perm内存大小。在用户生产环境上一般将这两个值设为相同,以减少运行期间系统在内存申请上所花的开销。
SurvivorRatio:设置YOUNG代中Survivor空间和Eden空间的比例

申请一块内存的过程:

A. JVM会试图为相关Java对象在Eden中初始化一块内存区域
B. 当Eden空间足够时,内存申请结束。否则到下一步
C. JVM试图释放在Eden中所有不活跃的对象(这属于1或更高级的垃圾回收);释放后若Eden空间仍然不足以放入新对象,则试图将部分Eden中活跃对象放入Survivor区/OLD区
D. Survivor区被用来作为Eden及OLD的中间交换区域,当OLD区空间足够时,Survivor区的对象会被移到Old区,否则会被保留在Survivor区
E. 当OLD区空间不够时,JVM会在OLD区进行完全的垃圾收集(0级)
F. 完全垃圾收集后,若Survivor及OLD区仍然无法存放从Eden复制过来的部分对象,导致JVM无法在Eden区为新对象创建内存区域,则出现”out of memory错误”

我们的一种resin服务器的jvm参数设置:

“-Xmx2000M -Xms2000M -Xmn500M -XX:PermSize=250M -XX:MaxPermSize=250M -Xss256K -XX:+DisableExplicitGC -XX:SurvivorRatio=1 -XX:+UseConcMarkSweepGC -XX:+UseParNewGC -XX:+CMSParallelRemarkEnabled -XX:+UseCMSCompactAtFullCollection -XX:CMSFullGCsBeforeCompaction=0 -XX:+CMSClassUnloadingEnabled -XX:LargePageSizeInBytes=128M -XX:+UseFastAccessorMethods -XX:+UseCMSInitiatingOccupancyOnly -XX:CMSInitiatingOccupancyFraction=60 -XX:SoftRefLRUPolicyMSPerMB=0 -XX:+PrintClassHistogram -XX:+PrintGCDetails -XX:+PrintGCTimeStamps -XX:+PrintHeapAtGC -Xloggc:log/gc.log”

是一种典型的响应时间优先型的配置。

Java中有四种不同的回收算法,对应的启动参数为
–XX:+UseSerialGC
–XX:+UseParallelGC
–XX:+UseParallelOldGC
–XX:+UseConcMarkSweepGC

1. Serial Collector
大部分平台或者强制 java -client 默认会使用这种。
young generation算法 = serial
old generation算法 = serial (mark-sweep-compact)
这种方法的缺点很明显,stop-the-world, 速度慢。服务器应用不推荐使用。

2. Parallel Collector
在linux x64上默认是这种,其他平台要加 java -server 参数才会默认选用这种。
young = parallel,多个thread同时copy
old = mark-sweep-compact = 1
优点:新生代回收更快。因为系统大部分时间做的gc都是新生代的,这样提高了throughput(cpu用于非gc时间)
缺点:当运行在8G/16G server上old generation live object太多时候pause time过长

3. Parallel Compact Collector (ParallelOld)
young = parallel = 2
old = parallel,分成多个独立的单元,如果单元中live object少则回收,多则跳过
优点:old old generation上性能较 parallel 方式有提高
缺点:大部分server系统old generation内存占用会达到60%-80%, 没有那么多理想的单元live object很少方便迅速回收,同时compact方面开销比起parallel并没明显减少。

4. Concurent Mark-Sweep(CMS) Collector
young generation = parallel collector = 2
old = cms
同时不做 compact 操作。
优点:pause time会降低, pause敏感但CPU有空闲的场景需要建议使用策略4.
缺点:cpu占用过多,cpu密集型服务器不适合。另外碎片太多,每个object的存储都要通过链表连续跳n个地方,空间浪费问题也会增大。

内存监控的方法:

1. jmap -heap pid
查看java 堆(heap)使用情况

using thread-local object allocation.
Parallel GC with 4 thread(s) //GC 方式

Heap Configuration: //堆内存初始化配置
MinHeapFreeRatio=40 //对应jvm启动参数-XX:MinHeapFreeRatio设置JVM堆最小空闲比率(default 40)
MaxHeapFreeRatio=70 //对应jvm启动参数 -XX:MaxHeapFreeRatio设置JVM堆最大空闲比率(default 70)
MaxHeapSize=512.0MB //对应jvm启动参数-XX:MaxHeapSize=设置JVM堆的最大大小
NewSize = 1.0MB //对应jvm启动参数-XX:NewSize=设置JVM堆的‘新生代’的默认大小
MaxNewSize =4095MB //对应jvm启动参数-XX:MaxNewSize=设置JVM堆的‘新生代’的最大大小
OldSize = 4.0MB //对应jvm启动参数-XX:OldSize=<value>:设置JVM堆的‘老生代’的大小
NewRatio = 8 //对应jvm启动参数-XX:NewRatio=:‘新生代’和‘老生代’的大小比率
SurvivorRatio = 8 //对应jvm启动参数-XX:SurvivorRatio=设置年轻代中Eden区与Survivor区的大小比值
PermSize= 16.0MB //对应jvm启动参数-XX:PermSize=<value>:设置JVM堆的‘永生代’的初始大小
MaxPermSize=64.0MB //对应jvm启动参数-XX:MaxPermSize=<value>:设置JVM堆的‘永生代’的最大大小


Heap Usage: //堆内存分步
PS Young Generation
Eden Space: //Eden区内存分布
capacity = 20381696 (19.4375MB) //Eden区总容量
used = 20370032 (19.426376342773438MB) //Eden区已使用
free = 11664 (0.0111236572265625MB) //Eden区剩余容量
99.94277218147106% used //Eden区使用比率
From Space: //其中一个Survivor区的内存分布
capacity = 8519680 (8.125MB)
used = 32768 (0.03125MB)
free = 8486912 (8.09375MB)
0.38461538461538464% used
To Space: //另一个Survivor区的内存分布
capacity = 9306112 (8.875MB)
used = 0 (0.0MB)
free = 9306112 (8.875MB)
0.0% used
PS Old Generation //当前的Old区内存分布
capacity = 366280704 (349.3125MB)
used = 322179848 (307.25464630126953MB)
free = 44100856 (42.05785369873047MB)
87.95982001825573% used
PS Perm Generation //当前的 “永生代” 内存分布
capacity = 32243712 (30.75MB)
used = 28918584 (27.57891082763672MB)
free = 3325128 (3.1710891723632812MB)
89.68751488662348% used


=====================================================================

jps
-q只输出进程ID,而不输出类的短名称
-m用于输出传递给Java进程(主函数)的参数
-l完整路径
-v显示传递给jvm的参数
10776@RedHat6 ~]$ jps -m -l -v
4345 sun.tools.jps.Jps -m -l -v -Denv.class.path=./:/opt/apps/jdk/lib:/opt/apps/jdk/lib/tools.jar -Dapplication.home=/opt/apps_install/jdk-1.6.0_25 -Xms8m

10776@RedHat6 ~]$ jps -q
4355

[@mhmaster.focus.cn ~]$ jps -v
14101 Resin -Dresin.server=app-0 -Djava.util.logging.manager=com.caucho.log.LogManagerImpl -Djava.system.class.loader=com.caucho.loader.SystemClassLoader -Djava.endorsed.dirs=/opt/data/jdk1.6.0_45/jre/lib/endorsed:/opt/data/resin//endorsed:/opt/data/resin//endorsed -Djavax.management.builder.initial=com.caucho.jmx.MBeanServerBuilderImpl -Djava.awt.headless=true -Dresin.home=/opt/data/resin/ -Xss1m -Xmx256m

-------------------------------------------
jstack -F 1355

Thread 1384: (state = BLOCKED)
- java.lang.Object.wait(long) @bci=0 (Interpreted frame)
- java.util.TimerThread.mainLoop() @bci=201, line=509 (Interpreted frame)
- java.util.TimerThread.run() @bci=1, line=462 (Interpreted frame)


Thread 1379: (state = BLOCKED)


Thread 1378: (state = BLOCKED)
- java.lang.Object.wait(long) @bci=0 (Interpreted frame)
- java.lang.ref.ReferenceQueue.remove(long) @bci=44, line=118 (Interpreted frame)
- java.lang.ref.ReferenceQueue.remove() @bci=2, line=134 (Interpreted frame)
- java.lang.ref.Finalizer$FinalizerThread.run() @bci=3, line=159 (Interpreted frame)


Thread 1377: (state = BLOCKED)
- java.lang.Object.wait(long) @bci=0 (Interpreted frame)
- java.lang.Object.wait() @bci=2, line=485 (Interpreted frame)
- java.lang.ref.Reference$ReferenceHandler.run() @bci=46, line=116 (Interpreted frame)


Thread 1375: (state = BLOCKED)
- java.lang.Object.wait(long) @bci=0 (Interpreted frame)
- java.lang.Object.wait() @bci=2, line=485 (Interpreted frame)
- org.apache.hadoop.ipc.Server.join() @bci=8, line=2082 (Interpreted frame)
- org.apache.hadoop.hdfs.server.namenode.NameNodeRpcServer.join() @bci=4, line=311 (Interpreted frame)

- org.apache.hadoop.hdfs.server.namenode.NameNode.join() @bci=4, line=639 (Interpreted frame)
- org.apache.hadoop.hdfs.server.namenode.NameNode.main(java.lang.String[]) @bci=39, line=1235 (Interpreted frame)

=====================================================================

想像一个Java进程在远程服务器上突然遇到频繁full GC的状况。我们只是想动态的改变HeapDumpBeforeFullGC与HeapDumpAfterFullGC参数来获取full GC前后的heap dump,并不想在侵入到Java程序内去通过代码做这个工作。这种场景里jinfo就能派上用场了——它已经把相关的JMX操作给封装好了。
(提醒:如果找不到打出来的heap dump的话,请设置HeapDumpPath。这个参数指定heap dump的目录。
-XX:HeapDumpPath=path/to/your/heap/dumps/dir)

上一篇其实已经提到了,通过jinfo -flag同样可以设置标记为manageable的VM参数。参考jinfo的帮助文档:
引用
Command prompt代码 收藏代码

$ jinfo -help
Usage:
jinfo [option] <pid>
(to connect to running process)
jinfo [option] <executable <core>
(to connect to a core file)
jinfo [option] [server_id@]<remote server IP or hostname>
(to connect to remote debug server)

where <option> is one of:
-flag <name> to print the value of the named VM flag
-flag [+|-]<name> to enable or disable the named VM flag
-flag <name>=<value> to set the named VM flag to the given value
-flags to print VM flags
-sysprops to print Java system properties
<no option> to print both of the above
-h | -help to print this help message


于是上一篇的实验可以用jinfo来做一次。

同样是在当前目录下放一个.hotspotrc文件来显示GC日志:
.hotspotrc代码 收藏代码

+PrintGCDetails


然后开groovysh来执行三次System.gc()。其中,第一次System.gc()之后在命令行调用下列命令:
Command prompt代码 收藏代码

$ jps
18711 Jps
18650 GroovyStarter
$ jinfo -flag +HeapDumpBeforeFullGC 18650
$ jinfo -flag +HeapDumpAfterFullGC 18650


然后在第二次System.gc()之后再调用:
Command prompt代码 收藏代码

$ jinfo -flag -HeapDumpBeforeFullGC 18650
$ jinfo -flag -HeapDumpAfterFullGC 18650


那么可以观察到Groovy Shell的运行状况是:
Groovysh代码 收藏代码

$ groovysh
[GC [PSYoungGen: 14016K->1344K(16320K)] 14016K->1344K(53696K), 0.0072690 secs] [Times: user=0.00 sys=0.00, real=0.00 secs]
[GC [PSYoungGen: 15360K->2288K(30336K)] 15360K->4824K(67712K), 0.0183850 secs] [Times: user=0.03 sys=0.00, real=0.01 secs]
Groovy Shell (1.7.7, JVM: 1.6.0_25)
Type 'help' or '\h' for help.
----------------------------------------------------------------------------------------------------------------------------
groovy:000> System.gc()
[GC [PSYoungGen: 26693K->2288K(30336K)] 29229K->8748K(67712K), 0.0262440 secs] [Times: user=0.05 sys=0.00, real=0.02 secs]
[Full GC (System) [PSYoungGen: 2288K->0K(30336K)] [PSOldGen: 6460K->8725K(37376K)] 8748K->8725K(67712K) [PSPermGen: 16933K->16933K(34176K)], 0.1172670 secs] [Times: user=0.11 sys=0.01, real=0.12 secs]
===> null
groovy:000> System.gc()
[GC [PSYoungGen: 2932K->256K(30336K)] 11658K->8981K(67712K), 0.0017600 secs] [Times: user=0.00 sys=0.00, real=0.00 secs]
[Heap Dump: Dumping heap to java_pid18650.hprof ...
Heap dump file created [18535501 bytes in 0.317 secs]
, 0.3208840 secs][Full GC (System) [PSYoungGen: 256K->0K(30336K)] [PSOldGen: 8725K->8918K(37376K)] 8981K->8918K(67712K) [PSPermGen: 17045K->17045K(38464K)], 0.1131950 secs] [Times: user=0.11 sys=0.00, real=0.11 secs]
[Heap DumpDumping heap to java_pid18650.hprof.1 ...
Heap dump file created [18440786 bytes in 0.318 secs]
, 0.3179790 secs]===> null
groovy:000> System.gc()
[GC [PSYoungGen: 1016K->160K(30336K)] 9935K->9078K(67712K), 0.0020120 secs] [Times: user=0.00 sys=0.00, real=0.00 secs]
[Full GC (System) [PSYoungGen: 160K->0K(30336K)] [PSOldGen: 8918K->9028K(37376K)] 9078K->9028K(67712K) [PSPermGen: 17077K->17077K(36928K)], 0.1111340 secs] [Times: user=0.11 sys=0.00, real=0.11 secs]
===> null
groovy:000> quit
Heap
PSYoungGen total 30336K, used 2427K [0x00000000edc00000, 0x00000000efbe0000, 0x0000000100000000)
eden space 28032K, 8% used [0x00000000edc00000,0x00000000ede5ef68,0x00000000ef760000)
from space 2304K, 0% used [0x00000000ef760000,0x00000000ef760000,0x00000000ef9a0000)
to space 2304K, 0% used [0x00000000ef9a0000,0x00000000ef9a0000,0x00000000efbe0000)
PSOldGen total 37376K, used 9028K [0x00000000c9400000, 0x00000000cb880000, 0x00000000edc00000)
object space 37376K, 24% used [0x00000000c9400000,0x00000000c9cd12b0,0x00000000cb880000)
PSPermGen total 36928K, used 17142K [0x00000000c4200000, 0x00000000c6610000, 0x00000000c9400000)
object space 36928K, 46% used [0x00000000c4200000,0x00000000c52bdbb0,0x00000000c6610000)


效果是:第二次System.gc()的时候,我们得到了两份HPROF格式的heap dump,而第一次与第三次都没有。

这样就可以很方便的在遇到full GC频繁的时候获取那么一两组heap dump来分析,而不需要在VM启动的时候就指定这两个参数——那样的话dump出来的文件就多了orz


====================================================================

jinfo -flag [+/-][flagName] [pid] #启用/禁止某个参数

jinfo -flag [flagName=value] [pid] #设置某个参数

对于上述的gc的情况,就可以使用以下命令打开heap dump并设置dump路径。

jinfo -flag +HeapDumpBeforeFullGC [pid]

jinfo -flag +HeapDumpAfterFullGC [pid]

jinfo -flag HeapDumpPath=/home/dump/dir [pid]

同样的也可以动态关闭。

jinfo -flag -HeapDumpBeforeFullGC [pid]

jinfo -flag -HeapDumpAfterFullGC [pid]


./jinfo -flags 3005
Attaching to process ID 3005, please wait...
Debugger attached successfully.
Server compiler detected.
JVM version is 25.60-b23
Non-default VM flags: -XX:CICompilerCount=15 -XX:+CMSClassUnloadingEnabled -XX:CMSFullGCsBeforeCompaction=0 -XX:CMSInitiatingOccupancyFraction=70 -XX:-CMSParallelRemarkEnabled -XX:ConcGCThreads=8 -XX:-DisableExplicitGC -XX:+HeapDumpAfterFullGC -XX:+HeapDumpBeforeFullGC -XX:InitialHeapSize=25769803776 -XX:InitialTenuringThreshold=5 -XX:MaxHeapSize=25769803776 -XX:MaxNewSize=12884901888 -XX:MaxTenuringThreshold=5 -XX:MinHeapDeltaBytes=196608 -XX:NewSize=12884901888 -XX:OldPLABSize=16 -XX:OldSize=12884901888 -XX:ParallelGCThreads=8 -XX:+PrintGC -XX:+PrintGCDetails -XX:+PrintGCTimeStamps -XX:+ScavengeBeforeFullGC -XX:SurvivorRatio=4 -XX:TargetSurvivorRatio=90 -XX:ThreadStackSize=256 -XX:-UseAdaptiveSizePolicy -XX:+UseCMSCompactAtFullCollection -XX:+UseCompressedClassPointers -XX:+UseCompressedOops -XX:+UseConcMarkSweepGC -XX:+UseFastUnorderedTimeStamps -XX:+UseParNewGC
Command line: -Xms24g -Xmx24g -Xmn12g -XX:SurvivorRatio=4 -Xss256k -XX:PermSize=256m -XX:MaxPermSize=256m -XX:-DisableExplicitGC -XX:+UseParNewGC -XX:+UseConcMarkSweepGC -XX:+UseCMSCompactAtFullCollection -XX:CMSFullGCsBeforeCompaction=0 -XX:+CMSClassUnloadingEnabled -XX:-CMSParallelRemarkEnabled -XX:CMSInitiatingOccupancyFraction=70 -XX:ParallelCMSThreads=8 -XX:ParallelGCThreads=8 -XX:MaxTenuringThreshold=5 -XX:-UseAdaptiveSizePolicy -XX:TargetSurvivorRatio=90 -XX:+ScavengeBeforeFullGC -XX:+PrintGC -XX:+PrintGCDetails -XX:+PrintGCTimeStamps -Dspring.profiles.active=online


其他优化建议

算法、逻辑上是程序性能的首要,遇到性能问题,应该首先优化程序的逻辑处理

优先考虑使用返回值而不是异常表示错误

查看自己的代码是否对内联是友好的: 你的Java代码对JIT编译友好么?

此外,jdk7、8在jvm的性能上做了一些增强:

通过-XX:+TieredCompilation开启JDK7的多层编译(tiered compilation)支持。多层编译结合了客户端C1编译器和服务端C2编译器的优点(客户端编译能够快速启动和及时优化,服务器端编译可以提供更多的高级优化),是一个非常高效利用资源的切面方案。在开始时先进行低层次的编译,同时收集信息,在后期再进一步进行高层次的编译进行高级优化。需要注意的一点:这个参数会消耗比较多的内存资源,因为同一个方法被编译了多次,存在多份native内存拷贝,建议把code cache调大一点儿(-XX:+ReservedCodeCacheSize,InitialCodeCacheSize)。否则有可能由于code cache不足,jit编译的时候不停的尝试清理code cache,丢弃无用方法,消耗大量资源在jit线程上。

Compressed Oops:压缩指针在jdk7中的server模式下已经默认开启。

Zero-Based Compressed Ordinary Object Pointers:当使用了上述的压缩指针时,在64位jvm上,会要求操作系统保留从一个虚拟地址0开始的内存。如果操作系统支持这种请求,那么就开启了Zero-Based Compressed Oops。这样可以使得无须在java堆的基地址添加任何地址补充即可把一个32位对象的偏移解码成64位指针。

逃逸分析(Escape Analysis): Server模式的编译器会根据代码的情况,来判断相关对象的逃逸类型,从而决定是否在堆中分配空间,是否进行标量替换(在栈上分配原子类型局部变量)。此外,也可以根据调用情况来决定是否自动消除同步控制,如StringBuffer。这个特性从Java SE 6u23开始就默认开启。

NUMA Collector Enhancements:这个重要针对的是The Parallel Scavenger垃圾回收器。使其能够利用NUMA (Non Uniform Memory Access,即每一个处理器核心都有本地内存,能够低延迟、高带宽访问) 架构的机器的优势来更快的进行gc。可以通过-XX:+UseNUMA开启支持。

此外,网上还有很多过时的建议,不要再盲目跟随:

变量用完设置为null,加快内存回收,这种用法大部分情况下并没有意义。一种情况除外:如果有个Java方法没有被JIT编译但里面仍然有代码会执行比较长时间,那么在那段会执行长时间的代码前显式将不需要的引用类型局部变量置null是可取的。具体的可以见R大的解释:https://www.zhihu.com/question/48059457/answer/113538171

方法参数设置为final,这种用法也没有太大的意义,尤其在jdk8中引入了effective final,会自动识别final变量。

JVM参数进阶

jvm的参数设置一直是比较理不清的地方,很多时候都搞不清都有哪些参数可以配置,参数是什么意思,为什么要这么配置等。这里主要针对这些做一些常识性的说明以及对一些容易让人进入陷阱的参数做一些解释。

以下所有都是针对Oracle/Sun JDK 6来讲

1. 启动参数默认值Java有很多的启动参数,而且很多版本都并不一样。但是现在网上充斥着各种资料,如果不加辨别的全部使用,很多是没有效果或者本来就是默认值的。一般的,我们可以通过使用java -XX:+PrintFlagsInitial来查看所有可以设置的参数以及其默认值。也可以在程序启动的时候加入-XX:+PrintCommandLineFlags来查看与默认值不相同的启动参数。如果想查看所有启动参数(包括和默认值相同的),可以使用-XX:+PrintFlagsFinal。输出里“=”表示使用的是初始默认值,而“:=”表示使用的不是初始默认值,可能是命令行传进来的参数、配置文件里的参数或者是ergonomics自动选择了别的值。

此外,还可以使用jinfo命令显示启动的参数。

jinfo -flags [pid] #查看目前启动使用的有效参数

jinfo -flag [flagName] [pid] #查看对应参数的值

这里需要指出的是,当你配置jvm参数时,最好是先通过以上命令查看对应参数的默认值再确定是否需要设置。也最好不要配置你搞不清用途的参数,毕竟默认值的设置是有它的合理之处的。

动态设置参数当Java应用启动后,定位到了是GC造成的性能问题,但是你启动的时候并没有加入打印gc的参数,很多时候的做法就是重新加参数然后重启应用。但这样会造成一定时间的服务不可用。最佳的做法是能够在不重启应用的情况下,动态设置参数。使用jinfo可以做到这一点(本质上还是基于jmx的)。

jinfo -flag [+/-][flagName] [pid] #启用/禁止某个参数

jinfo -flag [flagName=value] [pid] #设置某个参数

对于上述的gc的情况,就可以使用以下命令打开heap dump并设置dump路径。

jinfo -flag +HeapDumpBeforeFullGC [pid]

jinfo -flag +HeapDumpAfterFullGC [pid]

jinfo -flag HeapDumpPath=/home/dump/dir [pid]

同样的也可以动态关闭。

jinfo -flag -HeapDumpBeforeFullGC [pid]

jinfo -flag -HeapDumpAfterFullGC [pid]

其他的参数设置类似。

2. -verbose:gc 与 -XX:+PrintGCDetails很多gc推荐设置都同时设置了这两个参数,其实,只要打开了-XX:+PrintGCDetails,前面的选项也会同时打开,无须重复设置。

3. -XX:+DisableExplicitGC这个参数的作用就是使得system.gc变为空调用,很多推荐设置里面都是建议开启的。但是,如果你用到了NIO或者其他使用到堆外内存的情况,使用此选项会造成oom。可以用XX:+ExplicitGCInvokesConcurrent或XX:+ExplicitGCInvokesConcurrentAndUnloadsClasses(配合CMS使用,使得system.gc触发一次并发gc)代替。此外,还有一个比较有意思的地方。如果你不设置此选项的话,当你使用了RMI的时候,会周期性地来一次full gc。这个现象是由于分布式gc造成的,为RMI服务。具体的可见此链接内容中与dgc相关的:http://docs.oracle.com/javase/6/docs/technotes/guides/rmi/sunrmiproperties.html

4. MaxDirectMemorySize此参数是设置的堆外内存的上限值。当不设置的时候为-1,此值为-Xmx减去一个survivor space的预留大小。

5. 由于遗留原因,作用相同的参数

-Xss 与 -XX:ThreadStackSize

-Xmn 与 -XX:NewSize,此外这里需要注意的是设置了-Xmn的话,NewRatio就没作用了。

6. -XX:MaxTenuringThreshold使用工具查看此值默认值为15,但是选择了CMS的时候,此值会变成4。当此值设置为0时,所有eden里的活对象在经历第一次minor GC的时候就会直接晋升到old gen,survivor space直接就没用。

7. -XX:HeapDumpPath使用此参数可以指定-XX:+HeapDumpBeforeFullGC、-XX:+HeapDumpAfterFullGC、-XX:+HeapDumpOnOutOfMemoryError触发heap dump文件的存储位置。

参考资料

Java HotSpot? Virtual Machine Performance Enhancements

Java HotSpot Virtual Machine Garbage Collection Tuning Guide

[HotSpot VM] JVM调优的”标准参数”的各种陷阱

对于调优这个事情来说,一般就是三个过程:

性能监控:问题没有发生,你并不知道你需要调优什么?此时需要一些系统、应用的监控工具来发现问题。

性能分析:问题已经发生,但是你并不知道问题到底出在哪里。此时就需要使用工具、经验对系统、应用进行瓶颈分析,以求定位到问题原因。

性能调优:经过上一步的分析定位到了问题所在,需要对问题进行解决,使用代码、配置等手段进行优化。

Java调优也不外乎这三步。

此外,本文所讲的性能分析、调优等是抛开以下因素的:

系统底层环境:硬件、操作系统等

数据结构和算法的使用

外部系统如数据库、缓存的使用。
  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
Java的垃圾回收(Garbage Collection, GC)是由Java虚拟机(JVM)自动执行的内存管理机制。配置Java GC的主要目的是调整内存管理和垃圾回收策略,以达到更好的性能和内存利用率。 以下是一些常见的Java GCJVM配置选项: 1. 选择垃圾回收器(GC algorithm):Java提供了多种垃圾回收算法,如Serial GC、Parallel GC、CMS GC、G1 GC等。可以通过设置`-XX:+UseSerialGC`、`-XX:+UseParallelGC`、`-XX:+UseConcMarkSweepGC`、`-XX:+UseG1GC`等选项来指定使用的垃圾回收器。 2. 设置新生代和老年代大小:Java堆内存被分为新生代(Young Generation)和老年代(Old Generation),可以通过`-Xmn`选项设置新生代大小,通过`-Xmx`和`-Xms`选项设置堆最大和初始大小。 3. 调整垃圾回收的停顿时间:默认情况下,JVM会尽量减少垃圾回收过程对应用程序的停顿时间,但可能会牺牲一些吞吐量。可以通过`-XX:MaxGCPauseMillis`选项设置最大停顿时间。 4. 设置垃圾回收相关参数:可以通过一些参数来调整垃圾回收的行为,如`-XX:MaxTenuringThreshold`设置对象进入老年代的年龄阈值,`-XX:SurvivorRatio`设置新生代中Eden区和Survivor区的大小比例等。 5. 监控和调优:可以使用JVM提供的工具(如jstat、jconsole、jvisualvm等)来监控垃圾回收情况和内存使用情况,从而进行优化和调整。 需要注意的是,不同的应用程序和场景可能需要不同的GCJVM配置,具体的配置需要根据实际情况进行调整和优化。此外,建议在进行GCJVM配置调整时,先进行性能测试和监控,以确保配置的改变能够带来预期的效果。
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值