`

JAVA知识体系及虚拟机(全)

阅读更多

 JVM要点讲解图:

本次课程主要从以下几个部分讲解:

 

1.JAVA基本结构

1.1 JAVA逻辑结构图

1.2 java编译和执行流程

 1.2.1 Java代码编译器流程

 

1.2.2 jvm执行引擎流程

 

 

1.2.3 Java代码编译和执行期间的三个重要机制

  • Java源码编译机制

       Java 源码编译由以下三个过程组成:

       1.分析和输入到符号表

       2.注解处理

       3.语义分析和生成class文件

       流程图如下所示:

   

       最后生成的class文件由以下部分组成:

           3.1结构信息。包括class文件格式版本号及各部分的数量与大小的信息

           3.2 元数据。对应于Java源码中声明与常量的信息。包含类/继承的超类/实现的接口的声明信息、域与                  方法声明信息和常量池

           3.3 方法信息。对应Java源码中语句和表达式对应的信息。包含字节码、异常处理器表、求值栈与局                    部变量区大小、求值栈的类型记录、调试符号信息

  • 类加载机制

      JVM的类加载是通过ClassLoader及其子类来完成的,类的层次关系和加载顺序可以由下图来描述:

     

     1)Bootstrap ClassLoader

        负责加载$JAVA_HOME中jre/lib/rt.jar里所有的class,由C++实现,不是ClassLoader子类

     2)Extension ClassLoader

         负责加载java平台中扩展功能的一些jar包,包括$JAVA_HOME中jre/lib/*.jar

     3)App ClassLoader

         负责记载classpath中指定的jar包及目录中class

     4)Custom ClassLoader

         属于应用程序根据自身需要自定义的ClassLoader,如tomcat、jboss都会根据j2ee规范自行实现                  ClassLoader加载过程中会先检查类是否被已加载,检查顺序是自底向上,从Custom ClassLoader到           BootStrap ClassLoader逐层检查,只要某个classloader已加载就视为已加载此类,保证此类只所有             ClassLoader加载一次。而加载的顺序 是自顶向下,也就是由上层来逐层尝试加载此类。

 

  • 类执行机制 
  • JVM是基于栈的体系结构来执行class字节码的。线程创建后,都会产生程序计数器(PC)和栈(Stack),程序计数器存放下一条要执行的指 令在方法内的偏移量,栈中存放一个个栈帧,每个栈帧对应着每个方法的每次调用,而栈帧又是有局部变量区和操作数栈两部分组成,局部变量区用于存放方法中的 局部变量和参数,操作数栈中用于存放方法执行过程中产生的中间结果。栈的结构在下面内容会有讲解。

 

2.JVM内存模型

2.1 内存模型结构

 

2.2 内存组织结构

按照官方的说法:“Java 虚拟机具有一个堆,堆是运行时数据区域,所有类实例和数组的内存均从此处分配。堆是在 Java 虚拟机启动时创建的。”“在JVM中堆之外的内存称为非堆内存(Non-heap memory)”。可以看出JVM主要管理两种类型的内存:堆和非堆。简单来说堆就是Java代码可及的内存,是留给开发人员使用的;非堆就是JVM留给 自己用的,所以方法区、JVM内部处理或优化所需的内存(如JIT编译后的代码缓存)、每个类结构(如运行时常数池、字段和方法数据)以及方法和构造方法 的代码都在非堆内存中。

2.2.1 堆(heap  -Xms -Xmx -Xmn -XX:SurvivorRatio -XX:newRatio)

所有通过new创建的对象的内存都在堆中分配,其大小可以通过-Xmx和-Xms来控制。堆被划分为新生代和旧生代,新生代又被进一步划分为Eden和Survivor区,最后Survivor由From Space和To Space组成,结构图如下所示:

-新生代。新建的对象都是用新生代分配内存,Eden空间不足的时候,会把存活的对象转移到Survivor中,新生代大小可以由-Xmn来控制,也可以用-XX:SurvivorRatio来控制Eden和Survivor的比例

-旧生代。用于存放新生代中经过多次垃圾回收仍然存活的对象

 

 

 

相关计算公式:

总内存 = 堆内存(Xmx)+方法区内存(MaxPermSize)+栈内存(Xss)*线程数+直接内存(MaxDirectMemorySize,堆外)+虚拟机内存

例子:

     1. 配置程序JVM参数如下: -Xmx20M -Xms20M -Xmn10M -XX:SurvivorRatio=8 -XX:PermSize=10M -XX:MaxPermSize=10M  -Xss512k

     2. 实际内存分配:

           PS Young Generation(10M ,eden:from survivor:to survivor=8:1:1)

                     Eden Space: 8M    From Space:(1.0MB)  To Space:(1.0MB)

           PS Old Generation (10M)

           PS Perm Generation(10M)

           可以用jmap -heap pid查看分配情况:

          

2.2.2 栈(stack  -Xss)

每个线程执行每个方法的时候都会在栈中申请一个栈帧,由于每个线程正在执行的方法可能不同,因此每个线程都会有一个自己的Java栈,互不干扰。 每个栈帧包括局部变量区和操作数栈,用于存放此次方法调用过程中的临时变量、参数和中间结果,如图:

    

  • 局部变量表,就是用来存储方法中的局部变量(包括在方法中声明的非静态变量以及函数形参)。对于基本数据类型的变量,则直接存储它的值,对于引用类型的变量,则存的是指向对象的引用。
  • 操作数栈,程序中的所有计算过程都是在借助于操作数栈来完成的。
  • 指向运行时常量池的引用,因为在方法执行的过程中有可能需要用到类中的常量,所以必须要有一个引用指向运行时常量。
  • 方法返回地址,当一个方法执行完毕之后,要返回之前调用它的地方,因此在栈帧中必须保存一个方法返回地址。

栈存储数据: 

  •  1 基础数据类型 byte short int long float double char boolean
  •  2 方法的形式参数,方法调用完后从栈空间回收
  •  3 引用对象的地址,引用完后,栈空间地址立即被回收,堆空间等待GC

         a) 栈内的数据线程之间独立

         b) 具体细分为:

             b.1) 基本类型变量区

             b.2) 执行环境上下文

             b.3) 操作指令区  

 2.2.3 方法区(no-heap,-XX:PermSize -XX:PermMaxSize)

       用于存储已被虚拟机加载的类型信息、常量、静态变量、即时编译后的代码等信息。方法区是线程间共享的,当两个线程同时需要加载一个类型时,只有一个类会请求ClassLoader加载,另一个线程会等待。

对于每一个加载的类型,会在方法区中保存以下信息:

  • 类及其父类的全限定名(java.lang.Object没有父类)
  • 类的类型(Class or Interface)
  • 访问修饰符(public, abstract, final)
  • 实现的接口的全限定名的列表
  • 常量池
  • 字段信息
  • 方法信息
  • 除常量外的静态变量
  • ClassLoader引用
  • Class引用

对于每一个字段,会在方法区中保存以下信息(字段声明顺序也会保存):

  • 字段名
  • 字段的类型
  • 字段的修饰符(public, private , protected, static, final, volatile, transient)

对于每一个方法,会在方法区中保存以下信息(方法声明顺序也会保存):

  • 方法名
  • 方法返回类型(或void)
  • 参数信息
  • 方法修饰符(public, private, protected , static, final, synchronized, native, abstract)

如果方法不是抽象方法并不是本地方法(Native Method),还会保存以下信息:

  • 方法的字节码
  • 本地变量表及操作数栈的大小
  • 异常表

 

2.2.4 运行时常量池

Java是一种动态连接的语言,常量池的作用非常重要,常量池中除了包含代码中所定义的各种基本类型(如int、long等等)和对象型(如String及数组)的常量值还,还包含一些以文本形式出现的符号引用,比如:

  类和接口的全限定名;

  字段的名称和描述符;

  方法和名称和描述符。

java中的常量池技术,是为了方便快捷地创建某些对象而出现的,当需要一个对象时,就可以从池中取一个出来(如果池中没有则创建一个),则在需要重复重复创建相等变量时节省了很多时间。常量池其实也就是一个内存空间,不同于使用new关键字创建的对象所在的堆空间。

  • 常量池中对象和堆中的对象
  • 8种基本类型的包装类和对象池

java中基本类型的包装类的大部分都实现了常量池技术,这些类是Byte,Short,Integer,Long,Character,Boolean,另外两种浮点数类型的包装类则没有实现。另外Byte,Short,Integer,Long,Character这5种整型的包装类也只是在对应值小于等于127时才可使用对象池,也即对象不负责创建和管理大于127的这些类的对象.Integer的封装:

public static Integer valueOf(int i) {  
    final int offset = 128;  
    if (i >= -128 && i <= 127) { // must cache   
        return IntegerCache.cache[i + offset];  
    }  
      return new Integer(i);  
 }  
  
  
private static class IntegerCache {  
private IntegerCache(){}  
static final Integer cache[] = new Integer[-(-128) + 127 + 1];  
    static {  
        for(int i = 0; i < cache.length; i++)  
        cache[i] = new Integer(i - 128);  
    }  
}  

 由于cache[]在IntegerCache类中是静态数组,也就是只需要初始化一次,即static{......}部分,所以,如果Integer对象初始化时是-128~127的范围,就不需要再重新定义申请空间,都是同一个对象---在IntegerCache.cache中,这样可以在一定程度上提高效率。

 

2.2.5 堆外(offheap,-XX:MaxDirectMemorySize)

JDK1.4中引用了NIO,并引用了Channel与Buffer,可以使用Native函数库直接分配堆外内存,并通过一个存储在Java堆里面的DirectByteBuffer对象作为这块内存的引用进行操作。像我们使用的bigmemory就是堆外存,访问开销微秒级别。

详细参考这篇牛人博客::http://carlosfu.iteye.com/blog/2240426

 

2.2.6 对象访问

Reference在Java虚拟机中定义为指向对象的引用方式:

  • 直接指针访问方式(SUN公司hotspot JVM采用这种),reference变量中直接存储的就是对象的地址,而java堆对象一部分存储了对象实例数据,另外一部分存储了对象类型数据。
  • 间接句柄访问方式:java堆中将划分出一块内存来作为句柄池,reference中存储的就是对象的句柄地址,而句柄中包含了对象实例数据和类型数据各自的具体地址信息。

 

这两种访问对象的方式各有优势,使用句柄访问方式最大好处就是reference中存储的是稳定的句柄地址,在对象移动时只需要改变句柄中的实例数 据指针,而reference不需要改变。使用指针访问方式最大好处就是速度快,它节省了一次指针定位的时间开销,就JVM虚拟机而言,它使用的是第一种方式 (直接指针访问).

 

3.垃圾回收机制

 

3.1 垃圾回收器策略

3.1.1 垃圾回收器方式

  • 引用计数:比较古老的回收算法。原理是此对象有一个引用,即增加一个计数,删除一个引用则减少一个计数。垃圾回收时,只用收集计数为0的对象。此算法最致命的是无法处理循环引用的问题。

  • 对象引用遍历:

3.1.2 垃圾回收算法

    垃圾收集的四种算法:

 

  •   一. 标记-清除(Mark-Sweep):

图2 标记-清除策略

 

  此算法执行分两阶段。第一阶段从引用根节点开始标记所有被引用的对象,第二阶段遍历整个堆,把未标记的对象清除。此算法需要暂停整个应用,同时,会产生内存碎片。

  •  二.复制(Copying):

图3 复制策略

 

  此算法把内存空间划为两个相等的区域,每次只使用其中一个区域。垃圾回收时,遍历当前使用区域,把正在使用中的对象复制到另外一个区域中。此算法每次只处理正在使用中的对象,因此复制成本比较小,同时复制过去以后还能进行相应的内存整理,不会出现“碎片”问题。当然,此算法的缺点也是很明显的,就是需要两倍内存空间。

  •  三.标记-压缩(Mark-Compact):

图4 标记-压缩策略

此算法结合了“标记-清除”和“复制”两个算法的优点。也是分两阶段,第一阶段从根节点开始标记所有被引用对象,第二阶段遍历整个堆,把清除未标记对象并 且把存活对象“压缩”到堆的其中一块,按顺序排放。此算法避免了“标记-清除”的碎片问题,同时也避免了“复制”算法的空间问题。

 

  • 四.分代收集算法

    一般是把 Java 堆分为新生代和老年代,这样就可以根据各个年代的特点采用最适当的收集算法。在新生代中,每次垃圾收集时都发现有大批对象死去,只有少量存活,那就选用复制算法,只需要付出少量存活对象的复制成本就可以完成收集。而老年代中因为对象存活率高、没有额外空间对它进行分配担保,就必须使用“标记-清理”或“标记-整理”算法来进行回收。

 

3.1.3  选择合适的垃圾回收器

  1. 串行垃圾回收器(Serial Garbage Collector)
  2. 并行垃圾回收器(Parallel Garbage Collector)
  3. 并发标记扫描垃圾回收器(CMS Garbage Collector)
  4. G1垃圾回收器(G1 Garbage Collector)
  • 新生代GC

1. 串行GC(Serial GC)

 

触发时机:
创建新对象, Eden不足触发Young GC

收集过程:
Eden中存活对象复制到From移动到To。如此往复,直到目标区From/To不够时,将依然存活的对象放到Old

适用场景
单线程执行,适用于单CPU、新生代空间小、要求不高的应用。
默认:client模式或32位机

设置:
启用:-XX:+UseSerialGC
比例:-XX:SurivorRatio=8,如-Xmn=10MB,则Eden=8,From=To=1
 2.并行回收GC(Parallel Scavenge)

 

触发时机:
创建对象时,如果Eden空间不足,此对象大于等于Eden/2,则直接在Old上分配

适用场景:
多线程执行,适用于多CPU、要求高的应用。
默认:server模式(2核2GB)。

设置:
启用:-XX:+UseParallelGC指定
并发线程数:当CPU核数<=8时,为CPU核数;当多余8核时为3+(核数*5)/8,如16核为13线程。也可用-XX:ParallelGCThreads=4固定

比例:
Eden/From/To比例为-XX:InitialSurivorRatio=8控制,比如-Xmn=8MB,则Eden=6,From=To=1。
如果不配置该参数,可以通过-XX:SurivorRatio来控制,为其值+2。
会根据频率、消耗时间动态调整比例,可用-XX:-UseRSAdaptiveSizePolicy固定
 3.并行GC(ParNew GC)

 

适用场景:
与并行回收GC不同是,需配合Old使用CMSGC。原因是:ParNewGC不能与并行的旧生代GC同时使用。

启动方式:
启用:-XX:UseParNewGC
禁用GC:该GC也可以通过System.gc()来触发,如果想禁用该功能,可以设定-XX:DisableExplicit
 

 

 

  • 年老代GC

1.旧生代串行GC(Serial GC)

收集算法:
标记清除和标记压缩

适用场景:
采用单线程执行,耗时较长,执行时需暂停应用
默认: client模式或32位机默认采用这种方式

设置:
启用:-XX:+UseSerialGC
默认: client模式或32位机
-XX:+PrintGCApplicationStoppedTime查看GC造成的应用暂停时间。

 2.旧生代并行GC(Compacting)

收集算法:
标记压缩算法实现,内存分配和串行方式相同

适用场景:
采用多线程方式,做了优化,应用暂停时间缩短

启用方式:
与新生代相同,用-XX:+UseParallelGC指定
默认:server模式或非32位机默认采用这种方式

 3.旧生代并发GC(CMS:Concurrent Mark-Sweep GC)

收集算法:
标记清除算法实现

适用场景:
对GC并发进行,大大缩短应用暂停时间,但总GC时间会变长

启用方式:
-XX:UseConcMarkSweepGC
默认回收线程数: (并行GC线程数+3)/4,也可用-XX:ParallelCMSThreads=10指定
-XX:+CMSClassUnloadingEnabled来启用持久代使用CMS

 

 3.1.4 G1收集器

参考官网:http://www.oracle.com/webfolder/technetwork/tutorials/obe/java/G1GettingStarted/index.html

Oracle在JDK7 update 4之后开始完全支持G1垃圾收集器,G1是一个针对多处理器大容量内存的服务器端的垃圾收集器,其目标是在实现高吞吐量的同时,尽可能的满足垃圾收集暂停 时间的要求。在G1中,堆被划分成 许多个连续的区域(region)。每个区域大小相等,在1M~32M之间。JVM最多支持2000个区域,可推算G1能支持的最大内存为 2000*32M=62.5G。区域(region)的大小在JVM初始化的时候决定,也可以用-XX:G1HeapReginSize设置。在G1中没有物理上的Yong(Eden/Survivor)/Old Generation,它们是逻辑的,使用一些非连续的区域(Region)组成的。

新生代收集

  • Young Generation in G1

    The heap is split into approximately 2000 regions. Minimum size is 1Mb and maximum size is 32Mb. Blue regions hold old generation objects and green regions hold young generation objects.

     

    Note that the regions are not required to be contiguous like the older garbage collectors.

    A Young GC in G1

    Live objects are evacuated (i.e., copied or moved) to one or more survivor regions. If the aging threshold is met, some of the objects are promoted to old generation regions.

     

    This is a stop the world (STW) pause. Eden size and survivor size is calculated for the next young GC. Accounting information is kept to help calculate the size. Things like the pause time goal are taken into consideration.

    This approach makes it very easy to resize regions, making them bigger or smaller as needed.

    End of a Young GC with G1

    Live objects have been evacuated to survivor regions or to old generation regions.

     

    Recently promoted objects are shown in dark blue. Survivor regions in green.

    In summary, the following can be said about the young generation in G1:

    • The heap is a single memory space split into regions.
    • Young generation memory is composed of a set of non-contiguous regions. This makes it easy to resize when needed.
    • Young generation garbage collections, or young GCs, are stop the world events. All application threads are stopped for the operation.
    • The young GC is done in parallel using multiple threads.
    • Live objects are copied to new survivor or old generation regions.

 

老年代收集 

The G1 collector performs the following phases on the old generation of the heap. Note that some phases are part of a young generation collection.

 

Phase Description
(1) 标记阶段
(Stop the World Event)
This is a stop the world event. With G1, it is piggybacked on a normal young GC. Mark survivor regions (root regions) which may have references to objects in old generation.
(2) Root Region Scanning Scan survivor regions for references into the old generation. This happens while the application continues to run. The phase must be completed before a young GC can occur.
(3) Concurrent Marking Find live objects over the entire heap. This happens while the application is running. This phase can be interrupted by young generation garbage collections.
(4) Remark
(Stop the World Event)
Completes the marking of live object in the heap. Uses an algorithm called snapshot-at-the-beginning (SATB初始快照算法) which is much faster than what was used in the CMS collector.
(5) Cleanup
复制/清除(Stop the World Event and Concurrent)
  • 多线程清除失活对象,会有STW (Stop the world)
  • G1将回收区域的存活对象拷贝到新区域,清除Remember Sets. (Stop the world)
  • 并发清空回收区域并把它返回到空闲区域链表中 (Concurrent)
(*) Copying
(Stop the World Event)
These are the stop the world pauses to evacuate or copy live objects to new unused regions. This can be done with young generation regions which are logged as [GC pause (young)]. Or both young and old generation regions which are logged as [GC Pause (mixed)].

Initial Marking Phase

Initial marking of live object is piggybacked on a young generation garbage collection. In the logs this is noted as GC pause (young)(inital-mark).

 

Concurrent Marking Phase

If empty regions are found (as denoted by the "X"), they are removed immediately in the Remark phase. Also, "accounting" information that determines liveness is calculated.

 

 

Remark Phase

Empty regions are removed and reclaimed. Region liveness is now calculated for all regions.

 

 

Copying/Cleanup Phase

G1 selects the regions with the lowest "liveness", those regions which can be collected the fastest. Then those regions are collected at the same time as a young GC. This is denoted in the logs as [GC pause (mixed)]. So both young and old generations are collected at the same time.

 

After Copying/Cleanup Phase

The regions selected have been collected and compacted into the dark blue region and the dark green region shown in the diagram.

 

Summary of Old Generation GC

In summary, there are a few key points we can make about the G1 garbage collection on the old generation.

 

  • Concurrent Marking Phase
    • Liveness information is calculated concurrently while the application is running.
    • This liveness information identifies which regions will be best to reclaim during an evacuation pause.
    • There is no sweeping phase like in CMS.
  • Remark Phase
    • Uses the Snapshot-at-the-Beginning (SATB) algorithm which is much faster then what was used with CMS.
    • Completely empty regions are reclaimed.
  • Copying/Cleanup Phase
    • Young generation and old generation are reclaimed at the same time.
    • Old generation regions are selected based on their liveness.

 

 

3.1.5 新生代,老年代套餐搭配使用

FullGC可能原因:
–(1)System.gc();
–(2)旧生代空间不足(新生代对象转入、创建大对象/大数组)
–(3)持久代空间满(加载类、反射类、调用方法较多)
–(4)CMS GC时出现promotion failed(Young GC时From/To放不下,旧生代也放不下)和concurret mode failure(CMS GC同时有对象要放入旧生代,但空间不足)
–(5)统计Young GC时要移到旧生代的对象大小,大于旧生代剩余空间
–(6)–-XX:ScanengeBeforeFullGC来禁止Full GC时对新生代进行GC

 

3.2 相关参数配置

堆设置:

-Xms:初始堆大小

-Xmx:最大堆大小

-XX:NewSize=n:设置年轻代大小

-XX:NewRatio=n:设置年轻代和年老代的比值。如:为3,表示年轻代与年老代比值为1:3,年轻代占整个年轻代年老代和的1/4

-XX:SurvivorRatio=n:年轻代中Eden区与两个Survivor区的比值。注意Survivor区有两个。如:3,表示Eden:Survivor=3:2,一个Survivor区占整个年轻代的1/5

-XX:MaxPermSize=n:设置持久代大小

收集器设置:

-XX:+UseSerialGC:设置串行收集器

-XX:+UseParallelGC:设置并行收集器

-XX:+UseParalledlOldGC:设置并行年老代收集器

-XX:+UseConcMarkSweepGC:设置并发收集器

垃圾回收统计信息:

-XX:+PrintGC

-XX:+PrintGCDetails

-XX:+PrintGCTimeStamps

-Xloggc:filename

并行收集器设置:

-XX:ParallelGCThreads=n:设置并行收集器收集时使用的CPU数。并行收集线程数。

-XX:MaxGCPauseMillis=n:设置并行收集最大暂停时间

-XX:GCTimeRatio=n:设置垃圾回收时间占程序运行时间的百分比。公式为1/(1+n)

并发收集器设置:

-XX:+CMSIncrementalMode:设置为增量模式。适用于单CPU情况。

-XX:ParallelGCThreads=n:设置并发收集器年轻代收集方式为并行收集时,使用的CPU数。并行收集线程数。

G1相关参数设置:

Option and Default Value Description
-XX:+UseG1GC Use the Garbage First (G1) Collector
-XX:MaxGCPauseMillis=200                                          设置GC最大停顿时间
-XX:InitiatingHeapOccupancyPercent=45                                                                                                                                 启动并发GC周期的堆占用比例,  The default value is 45.
-XX:NewRatio=n Ratio of new/old generation sizes. The default value is 2.
-XX:SurvivorRatio=n Ratio of eden/survivor space size. The default value is 8.
-XX:MaxTenuringThreshold=15                                         Maximum value for tenuring threshold. The default value is 15.
-XX:ParallelGCThreads=n Sets the number of threads used during parallel phases of the garbage collectors. The default value varies with the platform on which the JVM is running.
   

4.监控工具和常用命令

    4.1 输出GC日志

     输出到控制台
-XX:+PrintGC简要信息
-XX:+PrintGCDetails详细信
-XX:+PrintGCTimeStamps时间戳
-XX:+PrintGCApplicationStoppedTime暂停时间

输出到文件
-Xloggc:/opt/gc.log

例如:java -Xms20M -Xmx20M
-Xmn10M -XX:SurvivorRatio=8 -XX:+UseParallelGC -verbose:GC -XX:+PrintGCDetails -XX:+PrintGCTimeStamps -Xloggc:/opt/test/gc.log DemoPSGC 
 

4.2 常用命令 

  • jps : jps可以理解为java的ps,用于显示java进程 ,-v 输出虚拟机启动的时的参数
  • jinfo:jinfo查看和调整虚拟机的各项参数

      格式:jinfo option pid

      option:

                 -flag <name> 显示JVM该属性的值

                 -flag [+|-]<name> 给该JVM增加获取去除某属性参数

                 -flag <name>=<value> 设置JVM某参数的值

  • jmap:jmap生成堆转存快照文件

        格式:jmap option pid

        option:

                 -dump 生成Java堆转存快照,例-dump:live,format=b,file=heap.bin pid

                 -heap 显示Java堆详细信息,如使用哪种回收器,参数配置、分代状况等

                -histo 显示堆中对象的统计信息,包含实例数量和容量(有时堆转储过大,可用此选项查看相应实例大小和数量,注意histo不要带live选项,否则会Full GC)

  • jstat:jstat 统计信息监视工具

       格式:jstat option pid interval count  

       option

                -gc 监视java堆状况、包含Eden区、2个survivor区,老年代、永久带的容量、已用空间、GC时间合计等

                -gcutil 主要关注已使用空间占总空间的百分比

               -gcnew

               -gcold

             以下选项关注使用的最小、当前、最大空间,可以用jmap -heap更易阅读

             -gcnewcapacity

             -gccapacity 

            -gcoldcapacity

           -gcpermcapacity

  • jstack:jstack生成当前时刻线程快照

           格式:jstack option pid

            检测cpu使用率飙高时三个步骤:

            1 获取占用率高的前10线程号: ps Hh -eo pid,tid,pcpu | sort -nk3 |tail > temp.txt

            2 转成16进制:awk '{print $2}' temp.txt |xargs printf "%x\n"

             3 从线程快照文件中搜索

4.3 常用工具

       4.3.1 jconsole,jvisualvm,jprofile,juc,mat

      

5.Linux监测

  •  CPU消耗分析

               top :进程/线程

               us高:线程粒度大,GC频繁,配合jstack定位线程

               sy高:线程粒度小,IO等待,配合jstack定位线程

               vmstat -1 :采样

               sar :历史

  • 内存消耗分析

              vmstat :弱点是不能分析进程内存

              swpd高:JVM内存大,线程多,ByteBuffer多

              sar -r :可分析历史,弱点是不能分析进程内存

              top:弱点是仅显示实际内存占用

  • 文件IO消耗分析

              iostat -x

              iowait高:文件读写长,磁盘/文件系统慢,文件太大,配合jstack定位线程

  • 网络IO消耗分析

              cat /proc/interrupts:查看网卡中断是否均衡分配到各CPU:修改kernel/MSI-X网卡

              tcpdump -i eth0 -s 0 -l -w - dst port 11214 | strings | grep test_

              sar -n ALL 1 2:只能统计收发包成功失败数量

 

6.JVM调优

•  内存管理
–代大小配置:决定了YoungGC和FullGC
•   GC策略
–GC次数
–GC时间
–应用暂停时间
  • 程序优化

 

更多参考:

1.jvm深入分析整理-知识体系(一)

2.JAVA深入分析整理-程序问题分析(二)

3.JVM重点内容-内存模型及结构(一)

4.JAVA深入分析整理-程序问题分析(二)

 

 

 

  • 大小: 95.2 KB
  • 大小: 16.3 KB
  • 大小: 9.2 KB
  • 大小: 16.7 KB
  • 大小: 18.2 KB
  • 大小: 100.5 KB
  • 大小: 26.1 KB
  • 大小: 40.8 KB
  • 大小: 26.6 KB
  • 大小: 25.7 KB
  • 大小: 30.6 KB
  • 大小: 24 KB
  • 大小: 44.7 KB
  • 大小: 27.3 KB
  • 大小: 11.2 KB
  • 大小: 180.7 KB
分享到:
评论
1 楼 carlosfu 2015-12-27  
   

相关推荐

    java知识体系总结

    Java知识体系总结 Java是一种广泛使用的面向对象的编程语言,由Sun Microsystems(现已被Oracle公司收购)于1995年推出。它以其“一次编写,到处运行”的特性闻名,适用于开发跨平台的应用程序,包括桌面应用、企业...

    JAVA8虚拟机(jvm)规范_Chinese version.rar

    《JAVA8虚拟机(jvm)规范_Chinese version》提供了关于JVM的详细中文指南,对于理解Java程序的运行机制、优化性能以及深入学习Java技术体系至关重要。下面我们将探讨一些重要的JVM知识点: 1. **内存模型**:JVM内存...

    Java虚拟机规范SE8英文

    ### Java虚拟机规范SE8知识点概述 #### 一、引言 - **历史背景**:Java虚拟机(JVM)自1995年首次发布以来,已经发展成为支持多种编程语言的重要平台。 - **Java虚拟机定义**:Java虚拟机(JVM)是一种能够执行Java...

    Java虚拟机

    以下是关于Java虚拟机及其相关知识点的详细说明: 1. **Java虚拟机的定义**: - **抽象规范**:Java虚拟机的规范定义了它的行为和功能,是一种理论模型。 - **具体实现**:不同的厂商根据规范实现自己的JVM,如...

    Java虚拟机规范(Java SE 8版) 带书签

    Java虚拟机(JVM)是Java编程语言的核心组成部分,它为Java程序提供了运行环境,使得代码能在任何支持Java的平台上无缝执行,实现了“一次编写,到处运行”的目标。《Java虚拟机规范(Java SE 8版)》是Oracle公司...

    JAVA核心知识点整理.zip

    9. **JVM内存模型**:理解Java虚拟机(JVM)的工作原理,特别是堆、栈、方法区等内存区域,以及垃圾收集机制,对于性能优化至关重要。 10. **设计模式**:设计模式是解决常见编程问题的模板,如单例、工厂、观察者...

    Java虚拟机规范中文版.pdf

    由于直接使用图片无法获取文本内容,我无法提供关于Java虚拟机规范的具体知识点。不过,我可以根据我所知,提供一些关于Java虚拟机规范的基础知识点,希望能够满足您的需求。 Java虚拟机(JVM)是执行Java字节码的...

    JAVA核心体系知识点.zip

    在这个"JAVA核心体系知识点.zip"压缩包中,主要包含的文件是"JAVA核心体系知识点.pdf",这是一份详尽的资料,深入探讨了Java虚拟机(JVM)、多线程、大数据处理以及分布式框架等主题。 首先,让我们来详细探讨Java...

    java虚拟机规范 java SE 7中文版

    《Java虚拟机规范 Java SE 7中文版》详细阐述了JVM的工作原理、内存管理、字节码执行机制以及相关的编程模型,是开发者深入理解Java技术体系的重要参考资料。 1. **JVM架构**:JVM主要由类加载器、运行时数据区、...

    深入Java虚拟机(原书第二版清晰版).

    类加载器分为引导类加载器、扩展类加载器和系统类加载器,它们共同构成了Java虚拟机的类加载体系。 最后,书中可能还会介绍Java虚拟机在不同平台上的实现,如何在不同操作系统上运行Java应用程序。Java虚拟机通过...

    java 体系结构图,不错的总结,复习的资料

    Java 体系结构图是理解Java编程语言及其生态系统的...对于初学者来说,理解这些知识点可以帮助构建完整的Java知识体系,进一步提升编程技能。在深入学习的过程中,建议结合实际编程练习,以更好地理解和掌握这些概念。

    javajvm虚拟机原理PPT课件.pptx

    下面是Java虚拟机的主要知识点: Java虚拟机生命周期 Java虚拟机的生命周期可分为三个主要阶段:装载、连接和初始化。每次启动一个Java程序,都会创建一个Java虚拟机实例,该实例将管理Java程序的生命周期。Java...

    深入理解Java虚拟机JVM高级特性与最佳实践1

    这本书旨在填补Java技术体系中关于Java虚拟机(JVM)知识的空白,帮助读者深入理解JVM的工作原理及其对程序性能的影响。JVM作为Java程序运行的基础,为开发者屏蔽了底层硬件和操作系统的复杂性,使得Java程序具有跨...

    java知识框架思维导图

    "Java知识框架思维导图"是整理和理解Java核心技术体系的一种有效工具,它可以帮助学习者系统地掌握Java的核心概念和架构。下面将根据这个主题详细阐述Java知识的主要框架。 一、基础语法 Java的基础语法包括变量、...

    java知识图谱.rar

    这个压缩包"java知识图谱.rar"包含了一系列与Java相关的主题,旨在帮助开发者构建一个全面的Java知识体系。以下是对其中各个关键知识点的详细阐述: 1. **JVM内存模型**: Java虚拟机(JVM)的内存模型是Java程序...

Global site tag (gtag.js) - Google Analytics