java代码的执行机制+JVM+GC

1.java源码编译机制

1.1 分析和输入到符号表(Parse and Enter)
    Parse:词法和语法分析
    Enter:将符号输入到符号表

1.2 注解处理(Annotation Processing)
    处理用户自定义的annotation

1.3 语义分析和生成class(Analyse and  Generate)
    Analyse:基于抽象语法树进行一系列的语义分析
    Generate:生成class,实例-》构造器、静态成员-》<clinit>、抽象语法树-》字节码(后序便利语法树)、最少代码转换。

class文件中包含的信息
*结构信息
*元数据
*方法信息

2.类加载机制
    指.class文件加载到JVM中,并形成Class对象的机制。
    可以在运行时动态加载.class

*装载(Load)-》链接(link){ 校验(Verify)->准备(Prepare)->解析(Resolve)可选操作}-》初始化(Initialize)

2.1 装载(Load)
    找到二进制字节码并加载到JVM中(标识:类的全限定名+ClassLoader实例ID)

2.2 链接(Link)
    对二进制字节码的格式进行校验、初始化静态变量、解析类中的借口、类。

2.3 初始化(Initialize)
    执行类中的静态初始化代码、构造器代码以及静态属性。

2.4 JVM类加载通过ClassLoader及其子类来完成
(加载顺序由上到下)

BootStrap Class Loader ->SJAVAHOME/jre/Lib/rt.jar
^
Extension Class Loader ->SJAVAHOME/jre/lib/ext/*.jar
(对应类名:ExtClassLoader)
^
System Class Loader -> SCLASSPATH
(对应类名:AppClassLoader)
^
User-Defined Class Loader
(开发人员继承ClassLoader自行实现的ClassLoader)
sati
类加载器委托机制:由最上面的类加载器开始加载类

3.JVM内存管理

方法区、堆、本地方法栈、PC寄存器、JVM方法栈

3.1 方法区
存放:类的信息(名称、修饰符等)、静态变量、final、Field、类中方法信息。
内存超过:OutOfMemory
大小调整
-XX:PermSize    最小值
-XX:MaxPermSize    最大值

3.2
存放:对象实例、数组值,new出来的对象
32位操作系统最大2G
-Xms    JVM启动时最小Heap内存
-Xmx    JVM启动时最大Heap内存
通常设置 -Xms 等于 -Xmx
-XX:MinHeapFreeRatio    当空余堆内存小于 40% 会增加到 -Xmx
-XX:MaxHeapFreeRatio    当空余堆内存大于 70% 会减小到 -Xms

-Xmn    新生代的大小
-XX:SurvivorRatio    调整Eden Space、Survivor Space的大小
-XX:PretenureSizeThreshold=1024    (单位字节,默认0)代表对象超过多大就不在新生代分配,而是直接在旧生代分配

旧生代内存 -Xmx 减去 -Xmn

3.3 本地方法栈
存放:每个native方法调用的状态

3.4 PC寄存器和JVM方法栈
存放:线程(每个线程会创建PC寄存器和JVM方法栈)
PC寄存器占用CPU寄存器或操作系统内存
JVM方法栈占用操作系统内存
JVM方法栈空间不足:StackOverflowError

-Xss    指定JVM方法栈大小


-XX:TLABWasteTargetPercent    设置TLAB 可占用Eden Space 的百分比,默认为1%
TLAB(Thread Local Allocation Buffer)

启动参数上增加
-XX:+PrintTLAB    查看TLAB空间的使用情况


-XX:SoftRefLRUPolicyMB    softReference(软引用)的存活时间,默认为1秒

-XX:MaxTenuringThreshold    在串行和ParNew方式时可设置,Minor GC中存活的次数为多少,才放入到旧生代

4. Sun JDK 中可用的GC

4.1 新生代可用GC

4.1.1 Serial GC (串行GC)
    整个扫描和复制都是单线程方式进行
-XX:+UseSerialGC    强制指定用此方法回收GC

4.1.2 Parallel Scavenge (并行回收GC)
    在多CPU的机器上采用多线程回收
-XX:InitialSurvivorRatio    设置Eden、S0、S1的比例划分、默认为8
jdk1.6后采用 -XX:SurvivorRatio

-XX:-UseAdaptiveSizePolicy    固定Eden、S0、S1的大小

-XX:+UseParallelGC    强制指定用此方法回收GC
-XX:ParallelGCThreads    强制指定线程数

4.1.3 ParNew (并行GC)
在配置为CMS GC的情况下,新生代默认采用并行GC方式
-XX:+UseParNewGC    强制指定

-XX:+DisableExplicitGC    禁止程序中调用System.gc 触发GC

4.2 旧生代可用的GC

4.2.1 串行

-XX:+PrintGCApplicationStoppedTime    查看GC造成的应用暂停的时间

5.异常
1.旧生代空间不足
java.lang.OutOfMemoryError: Java heap space

2.Permanet Generation 空间满
java.lang.OutOfMemoryError: PermGen space

3.CMS GC出现 Promotion failed 和 concurrent mode failure
增大survivor space、旧生代空间或调低触发兵法GC的比率
-XX: CMS MaxAbortablePrecleanTime=5 (单位为ms)避免CMS在remark完毕后很久才触发sweeping动作

启动时设置FullGC的执行间隔时间
-java -Dsum.rmi.dgc.client.gcInterval=3600000
禁止RMI调用 System.gc
-XX:+DisableExplicitGC

Sun JDK 提供两种简单方式现在GC
-XX:GCTimeRatio=n    设置JVM GC策略(吞吐量优先
-XX:MaxGCPauseMillis=n    设置JVM GC策略(暂停时间优先

6.新内容GC
Garbage First 简称G1:减少GC所导致的应用暂停时间,同时保持JVM堆空间的利用率

7.Real-Time JDK
1.新内存管理机制
Immortal、Scoped内存区域,均不受GC管理,基于这两个内存区域来编写应用完全不用担心GC会造成的暂停现象。

2.允许Java应用直接访问物理内存
不需要勇敢native code才能访问,能访问物理内存,直接将对象放入物理内存,而非JVM heap中。

8.JVM内存查看方法和分析工具
8.1 输出GC日志
    a.输入控制台:
    JVM启动参数加入-XX:PrintGC -XX:PrintGCDetails -XX:+PrintGCTimeStamps -XX:+PrintGCApplicationStoppedTime
    分别输出GC的简要信息、GC的详细信息、GC的时间信息、GC造成的应用暂停时间

    b.输入到指定文件
    JVM启动参数中再加入-Xloggc:gc.log

可用于GC跟踪分析的参数还有-verbose:gc、-XX:+PrintTenuringDistribution等

8.2 JConsole 
    JDK5自带工具,位于JDK的bin目录下,窗口化直接查看JVM信息

    JVisualVM
    JDK6 可查看JVM内存消耗,线程执行,消耗CPU、内存动作,可以安装VisualGC插件分析GC

    JMap
    JDK的bin目录,可以查看各个代的内存状况、JVM中对象的内存占用状况

    JHat 
    JDK6中自带肥西Jvm堆 dump 文件的,分析jvm heap中对象内存占用状况、以及引用关系。

    JStat
    JDK的bin目录下,除了分析GC,还可以用于分析编译的状况、class加载的状况等

    Eclipse Memory Analyzer
    Eclipse 提供用于分析jvm堆 dump文件的插件,对象内存占用、引用关系、分析内存泄漏等。
    http://www.eclipse.org/mat/    






posted @ 2014-03-06 10:12  有根竹子  阅读(1304)  评论(0编辑  收藏  举报