`

Java 内存模型,内存监控,GC查看

阅读更多

编写不易,转载请注明( 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
 
(六)GC 日志分析
 
[GC (Allocation Failure) [PSYoungGen(Young GC): 25872K(回收前大小)->3234K(回收后大小)(30208K)(新生代总大小)] 57740K(堆回收前大小)->39158K(堆回收后大小)(98816K)(堆总大小), 0.0006179 secs(回收时间)] [Times: user=0.00 sys=0.00, real=0.00 secs] 
[Full GC (Ergonomics) [PSYoungGen: 3234K->0K(30208K)] [ParOldGen: 35924K->6596K(68608K)] 39158K->6596K(98816K), [Metaspace: 2748K->2748K(1056768K)], 0.0016981 secs] [Times: user=0.01 sys=0.00, real=0.00 secs] 
 
引用
[GC [<collector>: <starting occupancy1> -> <ending occupancy1>, <pause time1> secs] <starting occupancy3> -> <ending occupancy3>, <pause time3> secs]
 
<collector>GC收集器的名称 
 
<starting occupancy1> 新生代在GC前占用的内存 
<ending occupancy1> 新生代在GC后占用的内存 
<pause time1> 新生代局部收集时jvm暂停处理的时间 
 
<starting occupancy3> JVM Heap 在GC前占用的内存 
<ending occupancy3> JVM Heap 在GC后占用的内存 
<pause time3> GC过程中jvm暂停处理的总时间  

(七)Java 程序启动脚本

#!/bin/bash

MAINCLASS=""
# add class path ---------------------------------
CLASSPATH=".."

for jar in `ls ./lib`
do
CLASSPATH="$CLASSPATH:./lib/$jar"
done

CLASSPATH="./classes:$CLASSPATH"

export CLASSPATH

# add java opts ----------------------------------

JAVA_OPTS="-Xms250m -Xmx250m -XX:MaxMetaspaceSize=50m"

#DEBUG="-Xdebug -Xnoagent -Djava.compiler=NONE -Xrunjdwp:transport=dt_socket,server=y,suspend=n,address=8899"

GC_LOG="-XX:+PrintGCDateStamps -XX:+PrintGCDetails -XX:+HeapDumpOnOutOfMemoryError -Xloggc:./logs/gc.log"

JAVA_OPTS="$JAVA_OPTS $DEBUG $GC_LOG"

# echo info ----------------------------------
echo "CLASSPATH : $CLASSPATH"
echo "JAVA_OPTS: $JAVA_OPTS"

nohup java $JAVA_OPTS -Dapp.base=$PWD $MAINCLASS >> /dev/null 2>&1 &

 

  • 大小: 8.1 KB
分享到:
评论

相关推荐

    java 内存监控

    Java内存监控是Java应用程序性能优化的关键环节,它可以帮助开发者识别并解决内存泄漏、垃圾收集问题以及潜在的服务器性能瓶颈。本文将深入探讨Java内存监控的相关知识点,并提供实用的命令工具来帮助你查找和解决...

    基于Java虚拟机内存模型的性能调优方法.zip

    Java内存模型,也称为JVM内存结构,主要包括堆内存、栈内存、方法区、程序计数器和本地方法栈五个部分。理解这些区域的工作原理对于进行性能调优至关重要。 - **堆内存**:存储所有类实例和数组,是所有线程共享...

    Java内存泄露及内存无法回收解决方案

    首先,我们要了解Java内存模型。Java虚拟机(JVM)中有三个主要的内存区域:堆内存(Heap)、栈内存(Stack)和方法区(Method Area)。其中,堆内存是Java对象的主要存储场所,栈内存主要存储方法调用时的局部变量...

    Java内存泄露检测

    首先,理解Java和C语言的内存管理模型至关重要。Java采用自动垃圾收集(GC)机制来管理内存,所有对象、实例和数组都在Java堆上分配。对象的生命周期由程序员决定,而GC负责回收不再使用的垃圾。然而,Java中的内存...

    Java内存监视器.rar

    Java内存模型主要分为三个区域:堆内存(Heap)、栈内存(Stack)和方法区(Method Area),在Java 8及以后版本,还包含了元空间(Metaspace)。每个区域都有其特定的用途: 1. **堆内存**:存储所有对象实例和数组...

    java 监视内存的使用情况

    总之,Java内存监控涉及多个层面,包括使用内置工具、编程接口、理解内存模型、掌握垃圾收集机制以及合理配置JVM参数。通过对这些知识点的深入学习和实践,我们可以有效地管理和优化Java应用的内存使用,提升系统...

    Java内存问题Java开发Java经验技巧共6页.pdf

    使用JVisualVM、JConsole等工具可以帮助开发者监控和诊断Java内存问题,查看内存分配、GC活动、线程状态等,找出潜在的问题。 以上内容涵盖了Java内存管理的核心知识点,理解和掌握这些原理与技巧,对于提升Java...

    java内存管理精彩概述

    VisualVM和GCViewer是强大的JVM监控工具,能够显示实时的内存使用情况、垃圾收集日志和性能指标,帮助诊断内存问题。 8. **内存溢出类型** - **堆内存溢出**:当堆不足以分配新对象时发生。 - **非堆内存溢出**...

    java 内存机制 配置 监控 整理

    Java内存管理中的关键组成部分之一是垃圾收集(Garbage Collection, GC),它自动回收不再使用的对象所占用的内存。主要的垃圾收集算法包括: 1. **引用计数(Reference Counting)**:每个对象包含一个引用计数器,当...

    Java GC的过程

    在理解GC之前,我们先来看一下Java内存模型。Java内存主要分为三个区域:堆(Heap)、栈(Stack)和方法区(Method Area)。其中,堆是GC的主要工作区域,用于存储对象实例;栈则为每个线程分配一个,存放基本类型...

    Java内存使用系列一Java对象的内存占用Java开发J

    Java内存模型分为堆内存和栈内存。堆内存是所有对象实例的存储区域,而栈内存则保存方法调用时的局部变量。栈内存的分配和回收非常快,但大小有限;堆内存分配较为复杂,但可以动态调整大小,适用于存储大型对象。 ...

    java 内存泄露分析流程

    分析和解决这些问题需要深入理解Java内存模型、垃圾收集机制以及JVM优化策略。以下是对这个主题的详细阐述: 1. **Java内存模型** Java内存主要分为堆内存(Heap)、栈内存(Stack)和方法区(Method Area)。堆...

    java监控系统链接和内存使用情况

    通过它们,可以查看内存分布、分析内存泄漏、追踪GC活动、检查连接状态等。 另外,JDK自带的`jmap`、`jstat`和`jinfo`等命令行工具,可以帮助开发者深入了解JVM的运行情况。例如,`jmap -histo`可显示堆内存中对象...

    30+个视频+深入理解Java虚拟机(jvm优化+内存模型+虚拟机原理)

    ### JVM内存模型 #### 堆内存(Heap) 堆是JVM管理的最大块内存区域,用于存储对象实例。堆被划分为新生代和老年代,其中新生代又细分为Eden区和两个Survivor区(S0和S1)。对象首先在Eden区创建,经过几次GC后会被移动...

    java实现的内存分配

    开发者还可以利用Java的内存分析工具(如VisualVM或JProfiler)来监控和诊断内存使用情况,找出可能导致内存泄漏或性能瓶颈的问题。 总的来说,理解和掌握Java中的内存分配策略对于编写高效、健壮的代码至关重要。...

    JVM内存模型以及垃圾回收相关资料

    JVM内存模型与垃圾回收是Java性能优化的关键部分。JVM(Java Virtual Machine)内存模型分为多个区域,包括新生代(New Generation)、老年代(Old Generation)和永久代(Permanent Generation)。新生代又细分为...

    Java虚拟机内存管理总结

    如果对象满足这两个条件,这些对象就可以判定为Java中的内存泄漏,这些对象不会被GC所回收,然而它却占用内存。 JVM的内存区域组成 Java把内存分两种:一种是栈内存,另一种是堆内存。在函数中定义的基本类型变量...

    基于Java虚拟机内存模型的性能调优方法.pdf

    JVM内存模型中的垃圾回收(GC)机制是其一大亮点,因为GC可以帮助程序员管理内存,降低内存泄漏的风险。然而,GC在回收内存的过程中采取的是标记-清除算法,它是一种停止-启动的算法,意味着在执行垃圾回收期间,...

    java内存分配演示程序

    "java内存分配演示程序"是一个用于理解Java内存模型和内存分配过程的项目。在这个课程设计中,你将深入学习Java如何在运行时为对象分配内存,以及垃圾收集器如何回收不再使用的内存。以下是关于Java内存分配的一些...

Global site tag (gtag.js) - Google Analytics