`

JVM基础知识

    博客分类:
  • JVM
 
阅读更多
2. Java运行时环境 — 其实就是考JVM

JVM与Hotspot的关系:JVM是规范,Hotspot是对规范的实现。

JVM三个部分必须非常清楚:内存划分、class加载机制、GC策略。

1)内存划分

我们常说的对于内存的划分,通常是指Hotspot的划分方式,而非JVM规范所规定的。
Hotspot将JVM内存划分为三个部分,Young Generation(年轻代)、Old Generation(年老代)、Perm Generation(永久代)。其中,Young Generation又分为Eden、From和To. 其中From和To又统称为Survivor Spaces(幸存区)。

对于内存的划分,可以没事用内存分析工具看看,如jmap, jvisualvm等等,观察下各个区域实际的变化。

JVM内存区模型:





















<1> 方法区:为多个线程共享
即“永久代”。存储:常量、静态变量、虚拟机加载的类信息
运行时常量池:是方法区的一部分。

<2> 虚拟机栈:线程私有
存放局部变量表、操作栈、方法出口等信息。每个方法从被调用到执行完的过程,都对应着一个栈帧在虚拟机栈中的从入栈到出栈的过程。

局部变量表存放的内容:
1)编译器已知的基本数据类型:boolean, byte, char, short, int, float, long, double.
2)对象引用(非对象本身)
注:double和long类型的数据会占用2个局部变量的空间,而其余数据类型只占1个。

<3> 本地方法栈:与虚拟机栈的区别是虚拟机栈为虚拟机执行的方法服务,而本地方法栈为Native方法服务。

<4> 堆:为多个线程共享
堆分为新生代和老年代

<5> 程序计数器:当前线程所执行字节码的行号指示器。



怎样判断是局部变量表呢?局部变量表所需的空间在编译期间就完全确定,在运行期间不会改变。

直接内存:除了JVM内存,Java用到的还有直接内存,即不是JVM规范中定义的内存区域。在NIO中引入了通道与缓冲区的IO方式,可以调用native方法直接分配堆外的内存,这个堆外的内存就是本机内存,本机内存不会影响堆内存的大小。

2)classloader机制

关于classloader,可以结合tomcat,了解清楚tomcat和classloader机制,看看tomcat是如何保证各个APP之间的类的隔离的。
待续。。。

JVM把class文件加载到内存,并对数据进行校验、解析、初始化,最终形成JVM可以直接使用的Java类型的过程,即为class loader机制。

类从被加载到JVM内存中开始,到卸载出内存为止,它的生命周期包括:加载(Loading)、验证(Verification)、准备(Preparation)、解析(Resolution)、初始化(Initialization)、使用(Using)、卸载(Unloading)七个阶段,其中验证、准备、解析三个部分成为链接。












解析和初始化的顺序有时会改变,有时在初始化之后再开始解析,如运行时动态绑定。

<1> 加载

主要步骤为:
通过“类的全名”来获取定义这个类的二进制字节流。
将字节流所代表的静态存储结构转换为方法区的运行时数据结构。
在Java堆中生成一个代表这个类的java.lang.Class对象,作为方法区这些数据的访问入口。

加载阶段可以使用系统提供的类加载器(ClassLoader)来完成,也可以自己实现类加载器。

<2> 验证:验证的主要目的是确保class文件的字节流是否符合当前虚拟机的要求,且不会危害虚拟机自身安全。

验证阶段分四个过程:文件格式验证、元数据验证、字节码验证、符号引用验证。

文件格式校验:class文件是否以魔术数0xCAFEBABE开头(class文件以cafebabe开头),主、次版本号是否在当前虚拟机处理范围内

元数据校验:对字节码做语义分析,看是否符合java语言规范。如除Object类以外的类是否存在父类,是否final类有被其他类继承等等。

字节码校验:对数据流和控制流分析,分析类的方法在运行时会不会有危害虚拟机的行为,如不能把一个父类对象赋值给子类对象。

符号引用校验:检查属性和方法的访问性(private, protected, public, default)是否可被当前类访问。

<3> 准备 — 为静态变量内存分配

准备阶段,是为类变量(即static变量,不是成员变量)分配内存并设置初始值的阶段,这些内存都分配到方法区中。例如:public static int value  = 12;
此时赋初始值为0,而不是12. 而赋值为12是在“初始化”阶段完成。

<4> 解析 — 为普通类内存分配

解析阶段是虚拟机常量池内的符合引用(符号引用是用一组符号来描述所引用的目标对象,符号引用与虚拟机实现的内存布局无关)替换为直接引用(直接引用是直接指向目标对象的指针、相对偏移量。直接引用与虚拟机的内存布局实现相关,即同一个符合引用在不同虚拟机上翻译出来的直接引用一般不会相同)的过程。主要对如下做解析:
类、接口、成员变量、方法

有了直接引用,那么引用的目标在内存中已经存在。

<5> 初始化 — 为成员变量赋初始值

初始化阶段是执行类的构造器<cIinit>方法的过程,在下面4种情况下初始化过程会被触发:

使用new实例化对象、读取或设置类的静态变量(同时被final修饰,已在编译器把结果放入常量池的静态常量除外)、调用类的静态方法,这时会生成4条字节码指令new, getstatic, putstatic, invokestatic, 如果类没有进行过初始化,则触发其初始化。
使用java.lang.reflect包的方法对类进行反射调用的时候
当初始化一个类,发现其父类还没有初始化过,需要先初始化其父类
JVM启动时,虚拟机会先初始化包含main方法的类

对于上面准备阶段所说的
public static int value = 12;
在准备阶段完成后,value的值为0,而在初始化阶段调用了类构造器<clinit>()方法,这个阶段完成后,value的值为12.

类的构造器<clinit>()方法是由编译器自动收集类中的所有类变量的赋值动作和静态语句块中的语句合并产生的,编译器收集的顺序跟语句在源文件中的顺序一致。

3)GC
http://www.cnblogs.com/zuoxiaolong/category/508918.html
待续。。。

跟踪收集器会全局记录所有对象之间的引用状态,执行时从GC Roots的对象作为起点,从起点向下搜索所有的引用链,当一个对象到GC roots没有任何引用链时,则证明对象是不可用的。













上图中,即使Object6, Object7, Object8互相引用,但由于对于GC roots不可达,所以他们被判定为可回收的对象。

可作为GC roots的对象包括:
虚拟机栈中的引用对象
方法区中的类静态属性引用的对象
方法区中常量引用的对象
本地方法栈中JNI的引用对象

在通过搜索算法判断对象引用链是否可达,判定对象是否存活都与“引用”有关。

引用主要分为“强引用”、“软引用”、“弱引用”、“虚引用”。强度依次递减。
<1> 强引用:对于成员变量Object obj = new Object(); 强引用的对象永远不会被清理。在不用的时候要这样做:obj = null; 之后new Object(); 才会被GC.

对于方法内的强引用:
public void test() {
Object o = new Object();
}
当方法结束时,new Object()就会被GC.

<2> 软引用:指一些还有用,但并非必须存在的对象。当JVM内存不足时,会被GC掉。
import java.lang.ref.SoftReference;

对于成员变量:
String str=new String("abc");                                     // 强引用
SoftReference<String> softRef=new SoftReference<String>(str);     // 软引用

对于softRef, 如果内存空间足够,则垃圾回收期不会GC它,不足时才回收它。
软引用可以用来实现内存敏感的高速缓存。

<3> 弱引用:它比软引用再弱些,被弱引用关联的对象,只能生存到下一次GC前,当GC工作时,无论内存是否足够,都会被GC掉。

String str=new String("abc");   
WeakReference<String> abcWeakRef = new WeakReference<String>(str);
str = null;

如果这个对象仅偶尔使用一下,并且希望在使用时随时就能获取到,但又不影响对象的垃圾收集,那么就应该用弱引用。

<4> 虚引用:又称为“欢迎引用”,它是最弱的一种引用。为一个对象设置虚引用的唯一目的就是希望能在这个对象被GC回收时,收到一个系统通知。

GC算法主要有复制、标记清除、标记压缩三种算法

4)内存调优

JVM调优主要针对内存管理方面的调优,即如何控制各个代的大小,GC策略。
由于GC开始垃圾回收时会暂停应用线程,这样会严重影响系统性能,调优的目的是为了尽量降低GC所导致的应用线程暂停时间、减少Full GC次数。

最关键参数:-Xms(初始堆大小)、 -Xmx(最大堆大小) 、-Xmn(新生代大小) 、XX:SurvivorRatio(Eden, s0, s1比率)、-XX:MaxTenuringThreshold(垃圾最大年龄)、-XX:PermSize(持久代初始值)、-XX:MaxPermSize(持久带最大值)

<1> -Xms、-Xmx:通常设置为相同的值,避免运行时要不断扩展JVM内存。
<2> -XMn: 新生代大小,新生代Eden、s0、s1的比率通过-XX:ServivorRatio来控制(例如值为4,表示Eden:S0:S1 = 4:3:3)
<3> -XX:MaxTenuringThreshold: 对象在经过多少次minor GC之后进入老年代
<4> -XX:PermSize、-XX:MaxPermSize: 指定方法去的大小,通常设置为相同的值。

设置参数要考虑的问题:

<1> 避免新生代大小设置过小:问题是,一是minor GC频繁;二是可能导致minor GC对象直接进入老年代。当老年代内存不足时,会触发Full GC

<2> 避免新生代大小设置过大:一是老年代变小,可能导致Full GC频繁;二是minor GC执行回收的时间增加

<3> 避免Survivor区过大或过小:

-XX:SurvivorRatio参数的值越大,Eden区越大,minor GC次数会降低,但两块Survivor区域(S0、S1)区域变小,如果超过Survivor区内存大小的对象在minor GC后仍没被回收,那么将不会从S0, S1之间互相copy, 而是直接进入老年代。

-XX:SurvivorRatio参数值设置过小,Eden区变小,minor GC次数会增加,Survivor区变大,意味着可存储更多的在minor GC存活的对象,避免其进入老年代

<4> 合理设置对象在新生代的存活的周期

默认-XX:MaxTenuringThreshold的值为15,即如果15次还没回收掉,第16次直接移入老年代。

5)类加载器(ClassLoader)

类加载器ClassLoader用来加载class字节码到JVM中。JVM这样使用Java类:
分享到:
评论

相关推荐

    JVM基础JVM基础JVM基础

    ### JVM基础知识详解 #### HotSpot简介 HotSpot作为Oracle(原属SUN)的主要Java虚拟机实现,自2006年起开源,并成为OpenJDK项目的核心组成部分。它主要使用C++编写,支持多种操作系统和硬件架构。HotSpot的一个...

    JVM基础知识及性能调优

    ### JVM基础知识及性能调优 #### 一、JVM架构概览 Java虚拟机(JVM)作为Java程序运行的基础环境,其内部结构复杂且高效。理解JVM的基础知识对于优化Java应用程序至关重要。JVM主要由以下几个关键部分组成: 1. **...

    JVM基础知识部分,帮助初识JVM

    了解并掌握这些JVM基础知识对于编写高性能、低内存消耗的Java程序至关重要。开发者可以通过理解JVM的工作原理,优化代码,避免内存溢出,提升应用的运行效率。此外,对JVM的深入研究也能帮助我们更好地理解Java平台...

    jvm基础知识与调优-jvm-training.zip

    JVM基础知识与调优是每一个Java开发者都需要掌握的重要技能。这个“jvm-training”资料包涵盖了JVM的核心概念、内存管理、垃圾回收机制、性能优化等方面的知识。 1. **JVM架构** - 类加载器:JVM通过类加载器将....

    jvm的基础知识总结

    JVM的基础知识涵盖了其内存模型、垃圾回收机制、线程模型等多个方面,下面将详细总结这些基础知识。 ### JVM内存模型 JVM内存模型主要可以分为线程共享区域和线程私有区域。 **线程共享区域** 1. 堆(Heap):...

    JVM基础.doc

    ### JVM基础知识精讲 #### 一、JVM概述与HotSpot简介 Java虚拟机(JVM)是Java技术的核心组成部分之一,它为Java程序提供了运行时环境。本节将详细介绍JVM的基本概念及其核心技术——HotSpot。 **HotSpot VM** 是...

    JVM基础知识及性能调优.pdf

    JVM的性能直接影响Java应用程序的运行效率,因此了解其基础知识和进行性能调优是每位Java开发者和系统架构师的必备技能。 首先,JVM的基本结构包括几个关键组件:类加载子系统负责加载Java类;Java栈存储线程运行时...

    JVM基础知识及分析工具

    一、Jdk组成 二、Jdk32与jdk64的差异 三、自动内存管理机制 四、内存泄露与内存溢出 五、垃圾回收算法 六、虚拟机性能监控工具

    JVM知识图谱.pdf

    - **内容**:涵盖JVM基础知识、JIT编译原理、字节码与机器码的区别等内容。 #### 三、JVM知识结构 - **知识结构**:包括基础概念、内存管理、类加载机制、JIT编译技术等方面。 #### 四、JIT编译器详解 - **JIT...

    JVM 基础 JAVA 并发 JVM 性能调优 LeetCode 算法 .......

    "JVM 基础知识点" JVM(Java Virtual Machine)是 Java 语言的运行环境,负责执行 Java 字节码。 JVM 的主要组件包括类加载器、字节码验证器、执行引擎和垃圾回收器等。 1. JVM 参数分类 JVM 参数可以分为三类:...

    jvm基础学习,介绍各种jvm里面的知识点,和深入理解java虚拟机很像,易懂

    ### JVM基础知识详解 #### JVM加载类的过程与机制 JVM(Java虚拟机)在加载类的过程中,遵循了一系列明确且有序的步骤。对于开发者而言,理解这些步骤有助于更好地掌握类加载的内部工作原理。 ##### 类加载的过程...

    JVM_调优基础(中英文对照版)

    #### 一、JVM基础知识 JVM(Java Virtual Machine)是运行Java程序的基础,它能够执行字节码(Bytecode),并提供了一个与平台无关的运行环境。对于JVM的基本理解有助于更好地进行调优工作。 1. **JRE (Java ...

    JVM课件(云析学院JVM课程课件)

    综上所述,文件中提供的内容是对JVM基础知识的一个概览,涵盖了Class文件格式、字节码、类加载机制、运行时数据区、垃圾回收策略、以及JVM在其他语言中的应用等多个方面。高级篇和优化篇预计会对JVM的高级特性和调优...

    jvm优化中文版

    JVM基础知识点中还涉及到Java编译器的不同模式。在JVM的解释模式下,字节码首先被解释执行,而实时编译(JIT)模式下,当某些代码段被频繁执行时,这些热点代码会被编译成本地代码以提高执行效率。JVM通过收集各种...

    JVM-Java虚拟机

    资源概要:JVM基础知识;类加载子系统;运行时数据区;对象的创建流程与内存分配; 对象内存布局;如何访问一个对象;GC基本原理;串行收集器;并行收集器; 能学到什么:1,JVM底层运行机制和原理;2JVM参数;3,...

    006-jvm性能调优

    JVM性能调优 JVM(Java Virtual Machine...JVM性能调优需要了解JVM基础知识、JVM参数调优、堆空间内存分配、垃圾收集等知识点,并结合实际应用中的需求和限制,选择合适的JVM参数配置和垃圾收集算法,以提高JVM性能。

    JVM从入门到实战1

    JVM基础知识 JVM是Java程序的运行环境,负责管理Java程序的生命周期。JVM主要由三个部分组成:类加载器、执行引擎和运行时数据区。类加载器负责加载Java类文件,执行引擎负责将Java字节码转换为机器码,并执行机器...

    这些不可不知的JVM知识.pdf

    Java虚拟机(JVM)是Java编程语言的核心组成部分,它为Java程序提供了跨平台的运行环境。JVM的全称是Java Virtual Machine,它将...因此,掌握这些JVM基础知识对于Java开发者来说是面试和实际工作中必不可少的知识点。

Global site tag (gtag.js) - Google Analytics