设为首页 加入收藏

TOP

JVM虚拟机深入理解+GC回收+类加载(一)
2019-08-24 00:07:13 】 浏览:126
Tags:JVM 虚拟 深入 理解 回收 加载

旭日Follow_24 的CSDN 博客 ,全文地址请点击:

https://blog.csdn.net/xuri24/article/details/81455449

一,前言

    本文章是读了“深入理解java虚拟机”一书的笔记记录和心得。作为一名Java的开发从业者或爱好者,想要在这条路继续和深入发展下去,了解和熟练掌握JVM虚拟机结构原理是作为技术人员的一项基础能力,掌握的深浅在某个方面衡量了一个技术人员的基本功个编程造诣。

    很多时候,我们去掌握一项技术知识,都是从工作中去学习并实践掌握真的印证那句:实践是检验真理的唯一标准!

但是,作为技术人员,想要扎实并深刻的掌握一项技术知识学习的先后顺序应为:。基本原理 - >学会使用 - >实践 - >回顾这样才会把一项技术知识学的透彻并牢固掌握。

二,JVM的基本介绍

Java程序设计语言,java虚拟机,javaApi类库三部分统称为JDK,JDK是用户支持java程序开发的最小环境。把java文件列入javaSe API子集和java虚拟机这两部分统称为JRE, JRE是支持的java程序运行的标准环境。

三,JVM基本结构

?

四,运行时数据区域

运行时数据区包括以下部分:

?

  • 程序计数器

程序计数器可以简单理解为:程序中每个线程运行时,当前线程所执行的字节码的行号指示器字节码工作时,通过这个计数器的值来选取下一条需要执行的字节码指令。分支,循环,跳转,异常处理,线程恢复等基础功能都需要依赖这个计数器来完成。每个线程的指令计数器独立互不影响。

  • Java的虚拟机栈

Java的虚拟机栈,是程序运行时,每个Java的方法创建的一个单独私有栈桢用以存储:。局部变量表,操作数栈,动态链接,方法出口灯信息每个方法从调用到执行完成,就对应着一个栈桢在虚拟机中从入栈到出栈的过程局部变量表存放了包括编译器产生的各种基本的java数据类型:布尔,字节,字符,短型,整型,浮点型,长,双等。它是一个对象引用,即指向对象起始地址的引用指针。

  • 本地方法栈

跟虚拟机栈类似,虚拟机栈存放的是为Java的方法服务的栈桢,而本地方法栈存放的是为虚拟机本身使用到的本地方法,可以理解为JDK加载时,调用JRE类库里面的本机方法所用到的栈桢。

  • Java的堆

java堆(Java Heap),是java虚拟机所管理的内存中最大的一块。是被所有线程共享的一块内存区域,在虚拟机启动时创建。唯一目的是:存放所有对象实例.java堆也是垃圾收集管理的主要区域(GC堆)。新生代,老年代/伊甸园,从幸存者空间,到幸存者空间等。

通常的Java堆是物理上不连续的内存空间,逻辑上连续的。类似磁盘空间,可以固定大小,也可以可扩展大小的。-XMX和-Xms控制等。

  • 方法区

方法区跟java的堆一样,各个线程共享的内存区域,它用于存放已经被虚拟机加载的类信息,常量,静态变量,即时编译的代码等数据。

这部分也是GC堆回收到的内存区域只是这部分,是比较难以回收到的区域,可类似看做:。永久代如常量池的回收和类型的卸载之类的工作。

  • 运行时常量池

运行时常量池是方法区的一部分,类文件中除了有类的版本,字段,方法,接口等描述信息外,还有一些是常量池,用于存放编译期间生成的各种字面量和符号引用。这部分内容将在类加载后进入方法区的运行时常量池中存放。

  • 直接内存

直接内存,并不是虚拟机运行时数据区的一部分也不是Java的虚拟机的内存区域可以简单理解为:。程序运行时的工作内存。

五,类加载机制

?

  • 加载

加载是“类加载”过程的一个阶段,这个阶段虚拟机需要完成以下三个事情:

1.通过一个类的全限定名来获取定义此类的二进制字节流。

2.将这个字节流所代表的静态存储结构转化为方法区的运行时数据结构。

3.在内存中生成一个代表这个类的java的,lang.Class对象,作为方法区这个类的各种数据的访问入口。

  • 验证

验证是连接阶段的第一步,这一阶段的目的是为了确保类文件的字节流中包含的信息符合当前虚拟机的要求,并且不会危害虚拟机自身的安全。

有如下验证:

1.文件格式验证,验证字节流是否符合类文件格式的规范,并且能够被当前版本的虚拟机处理如:主次版本号是否在当前虚拟机处理范围之内;常量池的常量中是否有不被支持的常量类型;类文件中各个部分及其文件本身是否有被删除的或附加的信息。

2.元数据验证,对字节码描述的信息进行语义分析,以保证其描述的信息符合的Java语言规范的要求,这个阶段可能包括:这个类是否有父类(除了java.lang.Object继承外,其他类都应有父类),这个类的父类是否继承了不允许被继承的类,这个类是不是抽象类,是否实现了其父类或接口之中要求实现的所有方法。

3.字节码验证,验证过程中最复杂的一个阶段,主要通过数据流和控制流分析,确定程序语义是合法的,符合逻辑的。对元数据信息中的数据类型做完校验后,这个阶段会对类的方法体进行校验分析,保证被校验类的方法在运行时不会做出危害虚拟机安全的事件。

4.符号引用验证,验证阶段最后步骤是发生在虚拟机将符号引用转化为直接引用的时候,这个转化动作将在连接的第三阶段 - 解析阶段中发生符号引用验证可以看做是对类自身以外的信息进行匹配性校验。

  • 准备

准备阶段是正式为类变量分配内存并设置类变量初始值的阶段,这些变量所使用的内存都将在方法区中进行分配注意是给变量分配初始值,区分:无最后普通变量定义准备阶段后,初始值为数据类型零值。当有最后的修饰的变量,准备阶段后该变量的初始值为定义的初始值。

  • 解析

。解析阶段是虚拟机将常量池内的符号引用替换为直接引用的过程包括如下内容:

1.类或接口的解析。

2.字段解析

3.类方法解析

4.接口方法解析

  • 初始化

初始化时类加载过程的最后一个阶段,前面阶段都是由虚拟机主导和控制,加载类的过程(除了用户自定义类加载器外)。初始化阶段,是执行类中定义的Java的程序代码(字节码)。

  • 类加载器

?

双亲委派模型,JAVA虚拟机存在两种不同的类加载器:

1.启动类加载器(Bootstrap ClassLoader),这个是虚拟机自身的一部分。通常虚拟机启动的时候,加载自身的一些类库的时候,也会由这个类加载器加载。

2.另外的是独立于虚拟机外的加载器,都继承自(java.lang.ClassLoader的)抽象类加载器。

从开发人员角度来看更细区分,而ClassLoader还分为:扩展类加载器(Extenxion ClassLoader)由sun.misc.Launcher&ExtClassLoader,负责加载<JAVA_HOME> \ lib \ ext目录中或被java.ext.dirs变量所指定路径中的所有类库,开发者可以直接使用扩展类加载器。

应用程序类加载器(Application ClassLoader),由sun.misc.Launcher和AppClassLoader实现。同时这个类是ClassLoader中的getSystemClassLoader()方法的返回值,一般称为系统类加载器。负责加载用户类路径(ClassPath)上指定的类库,开发者可以直

首页 上一页 1 2 下一页 尾页 1/2/2
】【打印繁体】【投稿】【收藏】 【推荐】【举报】【评论】 【关闭】 【返回顶部
上一篇ELK-elasticsearch-6.3.2插件【he.. 下一篇linux定时任务-crontab

最新文章

热门文章

Hot 文章

Python

C 语言

C++基础

大数据基础

linux编程基础

C/C++面试题目