编写不易,转载请注明( http://shihlei.iteye.com/blog/2244799)!
(一)Java 内存模型
摘自网上的内存模型图:
1)堆(heap——线程共享):实例域,静态域,数组元素。
(1)新生代(young generation): 新创建对象的存放区域
a)伊甸区(eden):
b)幸存者0(survivor0):
c)幸存者1(survivor1):
(2)老年代(tenured | old generation):
2)虚拟机栈(stack——线程不共享):局部变量,方法自定义参数,异常参数。线程私有
3)方法区(permanent generation):保存类常量,字符串常量,加载类的素有class
——Java 8 后 Metaspace 代替 默认受物理内存限制,可以通过 -XX:MaxMetaspaceSize 设置最大使用内存数。
4)程序计数器
5)本地方法栈
(二)JVM 内存设置
(1)设置参数
-Xms250m:java 堆初始值
-Xmx250m:java 堆最大值
-XX:MaxMetaspaceSize=50m 最大Metaspace大小
(2)查看
jmap -heap 18095
Attaching to process ID 18095, please wait...
Debugger attached successfully.
Server compiler detected.
JVM version is 25.31-b07
using thread-local object allocation.
Mark Sweep Compact GC
Heap Configuration:
MinHeapFreeRatio = 40
最小堆使用比例
MaxHeapFreeRatio = 70
最大堆可用比例
MaxHeapSize = 104857600 (100.0MB)
最大堆空间大小
NewSize = 34930688 (33.3125MB)
新生代分配大小
MaxNewSize = 34930688 (33.3125MB)
最大可新生代分配大小
OldSize = 69926912 (66.6875MB)
老生代大小
NewRatio = 2 (old/young generations)
新生代比例
SurvivorRatio = 8 (young/suvivor )
新生代与suvivor的比例
MetaspaceSize = 21807104 (20.796875MB)
Metaspace大小——
Metaspace是1.8后出现的,替代perm区
CompressedClassSpaceSize = 1073741824 (1024.0MB)
CompressedClassSpace大小
MaxMetaspaceSize = 52428800 (50.0MB) :
最大 Metaspace大小
G1HeapRegionSize = 0 (0.0MB)
|
(三)垃圾回收
1)MinorGC:清理年轻代(eden和survior)
eden满触发 eden—》s0如果此时s0满,触发s0-到s1
2)MajorGC:清理永久代
3)FullGC:清理整个堆空间,包括年轻和永久代,
如果"幸存者区"满,触发"幸存者"到"老年代GC"的FullGC,幸存者区满一定会出现MinorGC,所以 FullGC 一定会出现MinorGC, MajorGC永远不会出现。
(四)GC 参数:
-XX:+PrintGC 输出GC日志
-XX:+PrintGCDetails 输出GC的详细日志
-XX:+PrintGCTimeStamps 输出GC的时间戳(以基准时间的形式)
-XX:+PrintGCDateStamps 输出GC的时间戳(以日期的形式,如 2013-05-04T21:53:59.234+0800)
-XX:+PrintHeapAtGC 在进行GC的前后打印出堆的信息
-Xloggc:../logs/gc.log 日志文件的输出路径
注:PrintGC开始的参数都是可管理的GC参数,可以通过jinfo开启
如:
$ jinfo -flag +HeapDumpBeforeFullGC 18650
$ jinfo -flag +HeapDumpAfterFullGC 18650
$ jinfo -flag -HeapDumpBeforeFullGC 18650
$ jinfo -flag -HeapDumpAfterFullGC 18650
|
(五)GC监控及查看
1)查看对空间使用
jstat -gc vmid
S0C S1C S0U S1U EC EU OC OU MC MU CCSC CCSU YGC YGCT FGC FGCT GCT
3392.0 3392.0 0.0 2185.4 27328.0 21297.2 68288.0 3429.1 9216.0 8854.1 1024.0 939.1 3 0.039 2 0.037 0.076
3392.0 3392.0 0.0 2185.4 27328.0 21678.1 68288.0 3429.1 9216.0 8854.1 1024.0 939.1 3 0.039 2 0.037 0.076
3392.0 3392.0 0.0 2185.4 27328.0 22709.9 68288.0 3429.1 9216.0 8854.1 1024.0 939.1 3 0.039 2 0.037 0.076
3392.0 3392.0 0.0 2185.4 27328.0 23611.4 68288.0 3429.1 9216.0 8854.1 1024.0 939.1 3 0.039 2 0.037 0.076
3392.0 3392.0 0.0 2185.4 27328.0 24553.2 68288.0 3429.1 9216.0 8854.1 1024.0 939.1 3 0.039 2 0.037 0.076
|
S0C :S0 总大小
S1C :S1 总大小
S0U :S0 使用大小
S1U :S1 使用大小
EC :伊甸区总大小
EU :伊甸区使用大小
OC :老年代总大小
OU :老年代使用大小
MC :Metaspace 总大小
MU :Metaspace 使用大小
CCSC :CompressedClassSpace总大小
CCSU :CompressedClassSpace使用大小
YGC :Young GC 次数
YGCT :Young GC 消耗总时间
FGC :FullGC 次数
FGCT :FullGC 消耗总时间
GCT :GC总消耗时间
2)查看内存占用
查看占用内存最大的对象
jmap -histo 18095 | head -30
num #instances #bytes class name
----------------------------------------------
1: 52644 6436448 [B
2: 24249 3111416 [C
3: 9522 1066464 java.net.SocksSocketImpl
4: 15365 1029896 [Ljava.lang.Object;
5: 48790 780640 java.lang.Object
6: 3352 773088 [I
7: 9521 457008 java.net.SocketInputStream
8: 9521 457008 java.net.SocketOutputStream
9: 9564 382560 java.lang.ref.Finalizer
10: 15050 361200 java.lang.String
11: 9531 304992 java.io.FileDescriptor
12: 9521 304672 java.net.Socket
13: 11276 270624 java.net.InetAddress$InetAddressHolder
14: 3566 256752 org.apache.thrift.protocol.TBinaryProtocol
15: 9652 231648 java.util.ArrayList
16: 9523 228552 java.net.Inet4Address
17: 2417 193360 [S
18: 1448 153248 java.lang.Class
19: 3523 112736 java.util.concurrent.SynchronousQueue$TransferStack$SNode
20: 3522 84528 org.apache.thrift.protocol.TField
21: 3521 84504 org.apache.thrift.protocol.TMessage
22: 1786 71440 java.io.BufferedInputStream
23: 1785 71400 org.apache.thrift.transport.TSocket
24: 1758 70320 org.apache.thrift.transport.TTransportException
25: 1969 63008 java.util.HashMap$Node
26: 2613 62712 java.lang.StringBuilder
27: 1787 42888 java.io.BufferedOutputStream
|
3)查看栈线程情况
查看线程cpu,内存情况
ps -mp 32460 -o THREAD,tid,time
能看到进程cpu内存占用,线程cpu占用,看不到内存占用
ps -mp 32460 -o THREAD,tid,time,rss,size,%mem
USER %CPU PRI SCNT WCHAN USER SYSTEM TID TIME RSS SZ %MEM
root 0.0 - - - - - - 00:09:47 49416 2122256 4.8
root 0.0 19 - futex_ - - 32460 00:00:00 - - -
root 0.0 19 - futex_ - - 32461 00:00:00 - - -
root 0.0 19 - futex_ - - 32462 00:00:28 - - -
root 0.0 19 - futex_ - - 32463 00:00:00 - - -
root 0.0 19 - futex_ - - 32464 00:00:00 - - -
root 0.0 19 - futex_ - - 32465 00:00:00 - - -
root 0.0 19 - futex_ - - 32466 00:00:07 - - -
root 0.0 19 - futex_ - - 32467 00:00:01 - - -
root 0.0 19 - futex_ - - 32468 00:00:00 - - -
|
jstack -l 18095
"pool-1-thread-5" #12 prio=5 os_prio=0 tid=0x00007f60cc22f800 nid=0x724c waiting on condition [0x00007f60d106b000]
java.lang.Thread.State: WAITING (parking)
at sun.misc.Unsafe.park(Native Method)
- parking to wait for <0x00000000fba00b30> (a java.util.concurrent.SynchronousQueue$TransferStack)
at java.util.concurrent.locks.LockSupport.park(LockSupport.java:175)
at java.util.concurrent.SynchronousQueue$TransferStack.awaitFulfill(SynchronousQueue.java:458)
at java.util.concurrent.SynchronousQueue$TransferStack.transfer(SynchronousQueue.java:362)
at java.util.concurrent.SynchronousQueue.take(SynchronousQueue.java:924)
at java.util.concurrent.ThreadPoolExecutor.getTask(ThreadPoolExecutor.java:1067)
at java.util.concurrent.ThreadPoolExecutor.runWorker(ThreadPoolExecutor.java:1127)
at java.util.concurrent.ThreadPoolExecutor$Worker.run(ThreadPoolExecutor.java:617)
at java.lang.Thread.run(Thread.java:745)
Locked ownable synchronizers:
- None
|
"pool-1-thread-5" 线程名称。用户自己的程序最好是线程名称
prio=5 线程优先级默认是5
tid=0x00007f60cc22f800 唯一标识
nid=0x724c 对应系统线程的id和top出来看到的pid是对应的(十进制转16进制)
RUNNABLE线程状态
状态如下:
1,死锁 Deadlock(重要)
2,等待资源 Waiting on condition (重要)
3,等待获取监视器waiting on monitor entry
4,阻塞Blocked
5,执行中Runnable
6,暂停Suspended
7,对象等待中Object.wait()或TIMED_WAITING
8,停止Parked