JVM 基础知识

转 http://m.blog.csdn.net/article/details?id=51244791
JVM物理结构

这里写图片描述 
1、Heap(堆):一个Java虚拟实例中只存在一个堆空间 
2、MethodArea(方法区域):被装载的class的信息存储在Methodarea的内存中。当虚拟机装载某个类型时,它使用类装载器定位相应的class文件,然后读入这个class文件内容并把它传输到虚拟机中。 
3、JavaStack(java的栈):虚拟机只会直接对Javastack执行两种操作:以帧为单位的压栈或出栈 
4、ProgramCounter(程序计数器):每一个线程都有它自己的PC寄存器,也是该线程启动时创建的。PC寄存器的内容总是指向下一条将被执行指令的饿地址,这里的地址可以是一个本地指针,也可以是在方法区中相对应于该方法起始指令的偏移量。 
5、Nativemethodstack(本地方法栈):保存native方法进入区域的地址

Java代码编译和执行的整个过程

Java代码编译是由Java源码编译器来完成,流程图如下所示: 
这里写图片描述 
Java字节码的执行是由JVM执行引擎来完成,流程图如下所示: 
这里写图片描述

Java代码编译和执行的整个过程包含了以下三个重要的机制: 
1.Java源码编译机制 2.类加载机制 3.类执行机制 
Java源码编译机制 
Java 源码编译由以下三个过程组成:(javac –verbose 输出有关编译器正在执行的操作的消息) 
1.分析和输入到符号表 2.注解处理 3.语义分析和生成class文件

最后生成的class文件由以下部分组成: 
结构信息。包括class文件格式版本号及各部分的数量与大小的信息 
元数据。对应于Java源码中声明与常量的信息。包含类/继承的超类/实现的接口的声明信息、域与方法声明信息和常量池 
方法信息。对应Java源码中语句和表达式对应的信息。包含字节码、异常处理器表、求值栈与局部变量区大小、求值栈的类型记录、调试符号信息

类加载机制

JVM的类加载是通过ClassLoader及其子类来完成的,类的层次关系和加载顺序可以由下图来描述: 
这里写图片描述 
1)Bootstrap ClassLoader /启动类加载器 
JAVAHOMEjre/lib/rt.jarclassC++ClassLoader2ExtensionClassLoader/javajarJAVA_HOME中jre/lib/*.jar或-Djava.ext.dirs指定目录下的jar包 
3)App ClassLoader/ 系统类加载器 
负责记载classpath中指定的jar包及目录中class 
4)Custom ClassLoader/用户自定义类加载器(java.lang.ClassLoader的子类) 
属于应用程序根据自身需要自定义的ClassLoader,如tomcat、jboss都会根据j2ee规范自行实现ClassLoader 
加载过程中会先检查类是否被已加载,检查顺序是自底向上,从Custom ClassLoader到BootStrap ClassLoader逐层检查,只要某个classloader已加载就视为已加载此类,保证此类只所有ClassLoader加载一次。而加载的顺序是自顶向下,也就是由上层来逐层尝试加载此类。

JVM内存回收

Sun的JVMGenerationalCollecting(垃圾回收)原理是这样的:把对象分为年青代(Young)、年老代(Tenured)、持久代(Perm),对不同生命周期的对象使用不同的算法。(基于对对象生命周期分析) 
这里写图片描述 
(1)对新生代的对象的收集称为minor GC; 
(2)对旧生代的对象的收集称为Full GC; 
(3)程序中主动调用System.gc()强制执行的GC为Full GC。

GC查看工具—jstat

GC应该是程序优化的最后一步,GC执行的次数与创建对象的数量成正比,GC次数多的时候应该首先减少创建对象的数量。 
满足以下条件无需GC: 
Minor GC执行的很快(小于50ms) 
Minor GC执行的并不频繁(大概10秒一次) 
Full GC执行的很快(小于1s) 
Full GC执行的并不频繁(10分钟一次)

可以通过jstat -gcutil pid来查看GC情况,S0/S1/E/O/P分别表示survivor、eden、old、permanent空间已用百分比, 
YGC(Young GC)/YGCT表示Minor GC的次数和总共耗时(单位秒), 
FGC/FGCT表示Full GC的次数和总耗时,GCT=YGCT+ FGCT。

打印GC信息

-XX:+PrintGCApplicationConcurrentTime:打印每次垃圾回收前,程序未中断的执行时间 
-XX:+PrintGCApplicationStoppedTime:打印垃圾回收期间程序暂停的时间 
-XX:PrintHeapAtGC:打印GC前后的详细堆栈信息

GC一些原则:

通常-Xms1024m -Xmx1024m -XX:+UseG1GC就满足了需要 
初始堆大小和最大堆大小相等,避免堆空间的调整 
避免使用 -Xmn 选项或 -XX:NewRatio 等其他相关选项显式设置年轻代大小

JVM常见配置 
堆设置 
-Xms:初始堆大小 
-Xmx:最大堆大小 
-XX:NewSize=n:设置年轻代大小 
-XX:NewRatio=n:设置年轻代和年老代的比值 如: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:+UseG1GC 
垃圾回收统计信息 
-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数。并行收集线程数。

posted @ 2017-02-06 10:12  托马斯布莱克  阅读(314)  评论(0编辑  收藏  举报