原 荐 JVM笔记整理

不对之处还望指正。

垃圾回收

1. 如何判断对象是垃圾对象?

引用计数法

在对象中添加一个引用计数器,当有地方引用这个对象的时候,引用计数器的值+1,当引用失效时,则值-1. 此方式不能解决循环引用的问题。

  • 验证

添加gc日志,_005GC.java -verbose:gc -XX:+PrintGCDetails 发现hotspot不是使用此法。

可达性分析法

对象根root不可达。

  • 可以作为GCroots的对象
    • 虚拟机栈
    • 方法区的类属性所引用的对象
    • 方法区中常量所引用的对象
    • 本地方法栈中引用的对象。

2.如何回收?

回收策略

标记清除算法

通过可达性算法,标记出垃圾对象,将存活对象复制到S区,标记区域清空。

  • 效率问题

需要两步,先标记,后清除。

  • 空间问题

空间碎片严重,空间不连续,创建大对象时,需要检索到合适空间。

复制算法(新生代)

通过可达性算法,标记出垃圾对象,将存活对象复制到S区,标记区域清空可能是Eden,也可能是S0或S1的一个。 

    • 新生代
      • Eden 伊甸园
      • Survivor 存活区
      • Tenured Gen
    • 老年代
  • 方法区
  • 栈 本地方法栈 程序计数器

标记整理(老年代)

先标记要回收的垃圾对象,将需要回收的垃圾对象向一端移动,然后统一回收。基本是划分出一个区域,如果里面有不需要回收的,移动出去,需要回收的移进来,完毕后,回收该区域。

分代收集算法

根据分代,选择不同的算法,即复制算法和标记整理算法的结合。

垃圾回收器

Serial

  • 最基本的,1.3前唯一的选择
  • 单线程,串行。现常用于客户端

Parnew

  • 多线程收集器,可与CMS结合使用

Parallel Scavenge(新生代)

  • 复制算法
  • 多线程
  • 达到可控制吞吐量
  • -XX:MaxGCPauserMillis 垃圾收集器停顿时间

不是越小越好,越小可能回收的频率增高。比如原来10ms 设置为1 则会收集10次。

  • -XX:GCTimeRatio 吞吐量大小

吞吐量:CPU用于运行用户代码的时间与CPU消耗总时间的比值。

吞吐量=(执行用户代码时间)/(执行用户代码时间+垃圾回收占用时间)

cms(Concurrent Mark Sweep)

工作过程

  • 初始标记
  • 并发标记
  • 重新标记
  • 并发清理

优点

  • 并发收集
  • 低停顿

缺点

- 占用大量cpu资源

  • 无法处理浮动垃圾
  • 出现ConcurrentModeFailure
  • 空间碎片
  • cms收集老年代,ParNew收集新生代。

G1

历史

2004年已经提出

优势

  • 并行与并发。可以真正的不停止应用来收集垃圾。
  • 分代收集
  • 空间整合
  • 可预测的停顿

步骤

  • 初始标记
  • 并发标记
  • 最终标记
  • 筛选标记

与CMS比较

两者占用cpu资源都比较高,都是低停顿。而G1是划分区域(Region),即一块区域一块区域的,而传统的是整体划分了几个区域。

3.何时回收?

内存分配

内存分配策略

优先分配到Eden

优先分配到eden,如果容量不满足则触发一次mingc,

大对象直接分配到老年代

判定条件是eden区的一半,>=则晋升老年代 可以通过-XX:PretenureSizeThreshold=8M来设定阈值。

长期存活对象分配到老年代

可以通过-XX:MaxTenuringThreshold=15来设置,默认15

空间分配担保

-XX:HandlePromotionFailure

为了更好的适应不同程序的内存状况,对象年龄不是必须到达阈值才会进入老年代。 只要老年代的连续空间大于新生代对象总大小或者历次晋升的平均大小就会进行Minor GC,否则将进行Full GC。

动态对象年龄判断

如果在Survivor空间中相同年龄所有对象大小的总和大于Survivor空间的一半,年龄大于或等于该年龄的对象就可以直接进入老年代

  • 相关示意图
    • 堆空间 
    • Metaspace

虚拟机工具

jdk提供了很多工具,默认在bin目录中,基本都是依赖tools.jar文件。

jps

Java进程状态 类似linux的ps命令

  • 本地虚拟机唯一Id lvmid local virtual machine id
  • m 运行时传入主类的参数 入口传递的argument
  • v虚拟机参数
  • l 运行的主类全名或者包名
C:\Users\zdwljs>jps
2256
7376 RemoteMavenServer
12584 Launcher
4120 Jps
9644

C:\Users\zdwljs>jps -l
12176 sun.tools.jps.Jps
2256
7376 org.jetbrains.idea.maven.server.RemoteMavenServer
12584 org.jetbrains.jps.cmdline.Launcher
9644


C:\Users\zdwljs>jps -help
usage: jps [-help]
       jps [-q] [-mlvV] [<hostid>]

Jstat

类装载,内存,垃圾收集,jit编译信息。 官方文档

C:\Users\zdwljs>jstat -help
Usage: jstat -help|-options
       jstat -<option> [-t] [-h<lines>] <vmid> [<interval> [<count>]]

Definitions:
  <option>      An option reported by the -options option
  <vmid>        Virtual Machine Identifier. A vmid takes the following form:
                     <lvmid>[@<hostname>[:<port>]]
                Where <lvmid> is the local vm identifier for the target
                Java virtual machine, typically a process id; <hostname> is
                the name of the host running the target Java virtual machine;
                and <port> is the port number for the rmiregistry on the
                target host. See the jvmstat documentation for a more complete
                description of the Virtual Machine Identifier.
  <lines>       Number of samples between header lines.
  <interval>    Sampling interval. The following forms are allowed:
                    <n>["ms"|"s"]
                Where <n> is an integer and the suffix specifies the units as
                milliseconds("ms") or seconds("s"). The default units are "ms".
  <count>       Number of samples to take before terminating.
  -J<flag>      Pass <flag> directly to the runtime system.
C:\Users\zdwljs>jstat -gcutil 7376
  S0     S1     E      O      M     CCS    YGC     YGCT    FGC    FGCT     GCT
  0.00   0.00   4.44   2.55  96.40  91.49     73    0.206    72    2.594    2.799
  • 每隔1s执行一次,共监控10次。
C:\Users\zdwljs>jstat -gcutil 7376 1000 10
    S0     S1     E      O      M     CCS    YGC     YGCT    FGC    FGCT     GCT
    0.00   0.00   5.69   2.55  96.40  91.49     73    0.206    72    2.594    2.799
    0.00   0.00   5.69   2.55  96.40  91.49     73    0.206    72    2.594    2.799
    0.00   0.00   5.69   2.55  96.40  91.49     73    0.206    72    2.594    2.799
    0.00   0.00   5.69   2.55  96.40  91.49     73    0.206    72    2.594    2.799
    0.00   0.00   5.69   2.55  96.40  91.49     73    0.206    72    2.594    2.799
    0.00   0.00   5.69   2.55  96.40  91.49     73    0.206    72    2.594    2.799
    0.00   0.00   5.69   2.55  96.40  91.49     73    0.206    72    2.594    2.799
    0.00   0.00   5.69   2.55  96.40  91.49     73    0.206    72    2.594    2.799
    0.00   0.00   5.69   2.55  96.40  91.49     73    0.206    72    2.594    2.799
    0.00   0.00   5.69   2.55  96.40  91.49     73    0.206    72    2.594    2.799
Garbage-collected heap statistics.

S0C: Current survivor space 0 capacity (kB).

S1C: Current survivor space 1 capacity (kB).

S0U: Survivor space 0 utilization (kB).

S1U: Survivor space 1 utilization (kB).

EC: Current eden space capacity (kB).

EU: Eden space utilization (kB).

OC: Current old space capacity (kB).

OU: Old space utilization (kB).

MC: Metaspace capacity (kB).

MU: Metacspace utilization (kB).

CCSC: Compressed class space capacity (kB).

CCSU: Compressed class space used (kB).

YGC: Number of young generation garbage collection events.

YGCT: Young generation garbage collection time.

FGC: Number of full GC events.

FGCT: Full garbage collection time.

GCT: Total garbage collection time.

Jinfo

实时查看和调整参数

C:\Users\zdwljs>jinfo -flag UseConcMarkSweepGC 2256
-XX:+UseConcMarkSweepGC
C:\Users\zdwljs>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

Jmap

打印内存或者堆空间细节。 官方文档

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

where <option> is one of:
    <none>               to print same info as Solaris pmap
    -heap                to print java heap summary
    -histo[:live]        to print histogram of java object heap; if the "live"
                         suboption is specified, only count live objects
    -clstats             to print class loader statistics
    -finalizerinfo       to print information on objects awaiting finalization
    -dump:<dump-options> to dump java heap in hprof binary format
                         dump-options:
                           live         dump only live objects; if not specified,
                                        all objects in the heap are dumped.
                           format=b     binary format
                           file=<file>  dump heap to <file>
                         Example: jmap -dump:live,format=b,file=heap.bin <pid>
    -F                   force. Use with -dump:<dump-options> <pid> or -histo
                         to force a heap dump or histogram when <pid> does not
                         respond. The "live" suboption is not supported
                         in this mode.
    -h | -help           to print this help message
    -J<flag>             to pass <flag> directly to the runtime system
C:\Users\zdwljs>jmap -dump:format=b,file=d:\work\jvm\ricky.hprof 2256
Dumping heap to D:\work\jvm\ricky.hprof ...
Heap dump file created

利用上述方式进行快照生成,使用mat进行分析。

  • 存活实例
C:\Users\zdwljs>jmap -histo:live 2256 | more

 num     #instances         #bytes  class name
----------------------------------------------
   1:         60579       52974648  [B
   2:        305141       31563088  [C
   3:         32929       19770080  [I
   4:        302030        7248720  java.lang.String
   5:         61139        6692992  java.lang.Class
   6:         90152        6592144  [Ljava.lang.Object;
   7:         81443        2606176  java.util.HashMap$Node
   8:         48852        1563264  com.intellij.util.text.ByteArrayCharSequence
   9:         47477        1519264  org.jdom.Attribute
  10:         46998        1503936  java.util.concurrent.ConcurrentHashMap$Node
  11:          8922        1496016  [J
  12:          9889        1468048  [Ljava.util.HashMap$Node;
  13:         34702        1388080  java.util.LinkedHashMap$Entry
  14:         38597        1235104  com.intellij.util.containers.IntObjectLinkedMap$MapEntry
  15:         69142        1106272  java.lang.Integer
  16:         23246         929840  org.jdom.Element
  17:         35141         843384  com.intellij.util.SmartList
  18:         19850         794000  com.intellij.util.containers.hash.LinkedHashMap$Entry
  19:         18059         770664  [Lorg.jdom.Attribute;
  20:         23541         753312  org.jdom.ContentList
  21:         23246         743872  org.jdom.AttributeList
  22:         18580         743200  java.lang.ref.SoftReference
  23:         29987         719688  org.jdom.Text
  24:          6691         588808  java.lang.reflect.Method
  25:         18193         582176  java.util.Hashtable$Entry
  26:           479         517184  [F
  27:          8637         483672  java.lang.invoke.MemberName
  28:           600         468776  [Ljava.util.concurrent.ConcurrentHashMap$Node;
  29:         11516         460640  com.intellij.openapi.extensions.impl.ExtensionComponentAdapter
  30:          9436         452928  com.intellij.util.pico.CachingConstructorInjectionComponentAdapter
  31:          6834         451984  [Lorg.jdom.Content;
  32:          6935         443840  java.net.URL
  33:         17241         413784  java.util.ArrayList

jhat

JVM Heap Analysis Tool jvm堆分析工具

C:\Users\zdwljs>jhat -help
Usage:  jhat [-stack <bool>] [-refs <bool>] [-port <port>] [-baseline <file>] [-debug <int>] [-version] [-h|-help] <file>

        -J<flag>          Pass <flag> directly to the runtime system. For
                          example, -J-mx512m to use a maximum heap size of 512MB
        -stack false:     Turn off tracking object allocation call stack.
        -refs false:      Turn off tracking of references to objects
        -port <port>:     Set the port for the HTTP server.  Defaults to 7000
        -exclude <file>:  Specify a file that lists data members that should
                          be excluded from the reachableFrom query.
        -baseline <file>: Specify a baseline object dump.  Objects in
                          both heap dumps with the same ID and same class will
                          be marked as not being "new".
        -debug <int>:     Set debug level.
                            0:  No debug output
                            1:  Debug hprof file parsing
                            2:  Debug hprof file parsing, no server
        -version          Report version number
        -h|-help          Print this help and exit
        <file>            The file to read

For a dump file that contains multiple heap dumps,
you may specify which dump in the file
by appending "#<number>" to the file name, i.e. "foo.hprof#3".

All boolean options default to "true"
  • 示例

指定快照地址,以及本地http端口

C:\Users\zdwljs>jhat -port 1234 d:\work\jvm\ricky.hprof
Reading from d:\work\jvm\ricky.hprof...
Dump file created Mon Apr 02 13:39:22 CST 2018
Snapshot read, resolving...
Resolving 6152505 objects...
Chasing references, expect 1230 dots..............................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................
Eliminating duplicate references..............................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................
Snapshot resolved.
Started HTTP server on port 1234
Server is ready.

jsack

打印一个Java线程栈追踪信息,官方文档

C:\Users\zdwljs>jstack -help
Usage:
    jstack [-l] <pid>
        (to connect to running process)
    jstack -F [-m] [-l] <pid>
        (to connect to a hung process)
    jstack [-m] [-l] <executable> <core>
        (to connect to a core file)
    jstack [-m] [-l] [server_id@]<remote server IP or hostname>
        (to connect to a remote debug server)

Options:
    -F  to force a thread dump. Use when jstack <pid> does not respond (process is hung)
    -m  to print both java and native frames (mixed mode)
    -l  long listing. Prints additional information about locks
    -h or -help to print this help message
  • 实例
C:\Users\zdwljs>jstack -l 2256
2018-04-02 14:10:41
Full thread dump OpenJDK 64-Bit Server VM (25.152-b15 mixed mode):

"ApplicationImpl pooled thread 2513" #4852 daemon prio=4 os_prio=-1 tid=0x000000005907a000 nid=0x3178 waiting on condition [0x000000007e48f000]
   java.lang.Thread.State: WAITING (parking)
        at sun.misc.Unsafe.park(Native Method)
        - parking to wait for  <0x00000000e0f37c70> (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

本文参与腾讯云自媒体分享计划,欢迎正在阅读的你也加入,一起分享。

发表于

我来说两句

0 条评论
登录 后参与评论

相关文章

来自专栏Java架构师历程

JVM 内存分代、垃圾回收漫谈

关于 JVM 内存模型以及垃圾回收的文章网上很多,自己以前也看过很多,但是却从来也没有系统的去了解学习过,这次正巧看到一本讲解 JVM 的好书 – 周志明老师的...

702
来自专栏JAVA烂猪皮

面试必问之JVM原理

JVM是Java Virtual Machine(Java虚拟机)的缩写,JVM是一种用于计算设备的规范,它是一个虚构出来的计算机,是通过在实际的计算机上仿真模...

892
来自专栏影子

关于垃圾回收的一些基本原理及技术解析

3388
来自专栏搜云库

《深入理解Java虚拟机》(三)垃圾收集器与内存分配策略

垃圾收集器与内存分配策略 详解 3.1 概述 本文参考的是周志明的 《深入理解Java虚拟机》第三章 ,为了整理思路,简单记录一下,方便后期查阅。 3.2 对...

28610
来自专栏海纳周报

Java的分代式GC

要说理解JVM的垃圾回收,什么引用计数,Copy GC,mark & compaction好像都不是必须要掌握的东西。真要说对普通的Java程序员比较重要的东西...

3399
来自专栏积累沉淀

Java 内存区域和GC机制

Java垃圾回收概况   Java GC(Garbage Collection,垃圾收集,垃圾回收)机制,是Java与C++/C的主要区别之一,作为Java开发...

19310
来自专栏影子

关于垃圾回收的一些基本原理及技术解析

1103
来自专栏小勇DW3

JVM调优日志解析分析

-XX:+PrintGCTimeStamps 输出GC的时间戳(以基准时间的形式)

812
来自专栏java一日一条

JVM 内存分代、垃圾回收漫谈

关于 JVM 内存模型以及垃圾回收的文章网上很多,自己以前也看过很多,但是却从来也没有系统的去了解学习过,这次正巧看到一本讲解 JVM 的好书 – 周志明老师的...

814
来自专栏博客园迁移

JVM参数配置 java内存区域

       http://www.importnew.com/18694.html

612

扫码关注云+社区