java虚拟机基础

       从今天开始我们学习一下java的基础知识JVM,之前一直觉得没必要,因为感觉用不到,但是这样就导致根基不稳,那么你在java中的造诣也不会高到那里去。作为一个开发人员,我们不应该排斥技术,所以今天我们就开始重新了解一些下ava虚拟机之JVM。

       本文适合小白,高手请绕行,打扰了!另外本文不会很深度讲解虚拟机,因为那不是一时半会就可以理解的。

什么是java虚拟机(JVM)

答:

       1:java中的源文件 .java文件,会被编译成 .class字节码文件,然后字节码文件(.class)会被java的虚拟机编译成为机器可以识别的机器码文件,不同的平台的机器码不同,但是不同的平台装有不同的虚拟机(JVM),虽然不同,但是都可以处理相同的.class字节码文件,然后转换为可以让机器运行的机器码。这也是为什么说java是一个跟平台无关的编程语言。(这也是为什么需要安装JDK)

       2:java虚拟机是一个抽象的概念,每一个java程序都包含独立的一个jvm,他们的起点都是我们的Main方法,也称之为主线程,他是程序的入口。

       3:在jvm中有它自己想象的一套硬件和处理器,如:处理器、堆栈、寄存器还有响应的指令系统。这些东西与我们的java程序运行西西相关。

JVM的生命周期与体系架构

       类装载子系统:在JVM中负责查找并装载类型的那本分被称为类装载子系统,JVM有两种类装载器,启动类装载器和用户自定义的类装载器。步骤如下(1)装载:查找并装载类型的二进制数据 (2)连接:执行验证、准备以及解析   验证——确保被导入的类型的正确性、准备——为类变量分配内存,并将其初始化为默认值。解析——吧类型中的符号转换为直接引用。(3)初始化:把类型变量初始化为正确的初始值。

       方法区:关于装载类型的信息被存储在 一个逻辑上被称为方法区的内存中,类的类变量同样存储在方法区中。所有线程共享方法区,因此,他们对方法去的数据访问必须被设置成线程安全的。JVM方法区中储存了1、类型的全限定名;2、这个类型的超类的全限定名;3、这个类型是接口还是类类型等 除此之外,JVM还为每个被装载的类型存储以下信息,1、该类的常量池,就是该类型所用常量的一个有序集合,包括直接常量和对其他类型、字段、方法的符号引用。2、字段信息、3、除了常量外的所有类的静态变量。(hotspot用永久带实现方法区),说简单点就是:类的信息,常量,静态资源等是放在方法区中,他们不会给垃圾回收,但是可能会被fullGc回收。

       :一个Java虚拟机实例中只存在一个堆空间,因此所有的线程都共享这个堆。又由于一个Java程序独占一个JVM实例,因此每个JAVA程序都有自己的堆空间,他们不会彼此干扰,但同一个java程序的多个线程共享一个堆空间。所有的实例对象都在这上面进行分配,也是GC管理的重要区域。(堆还可以细分新生代和老年代,新生代又可以分为eden 、form Survivor和to Survivor空间等) ,说简单点:就是所有通过new关键字创建的对象都会保存在堆中,当然包括数组,包括八大基本数据类型的包装类型。

       程序计数器:每个线程都有自己的PC寄存器,他的线程启动时创建,大小是一个字长,当执行本地方法时,PC寄存器内容是是吓一跳被执行指令的地址。(当前线程执行的字节码的行号显示)

扫描二维码关注公众号,回复: 8957419 查看本文章

       JAVA虚拟机栈:每当启动一个新的线程时,JVM都会为它分配一个Java栈。Java栈是保存线程的状态,JVM只会对其进行入栈和出栈,每当调用一个JAVA方法时,虚拟机都会在该线程的Java栈压入一个新帧,来存储参数、局部变量、中间运算结果。Java栈上所有的数据都是这个线程所独有的。说简单点:基本数据类型,局部变量都是保存在栈中,每一个线程是一个独立的栈

       本地方法栈:本地方法栈实际上依赖于JVM实现的,设计者可以根据自己需求使用Java程序调用本地方法。java语言调用外部语言(java最底层是c语言),native,调用的是底层的c语言方法,java中可以使用native调用其他语言,可以看到原子类中的底层使用了native关键字,调用了一些底层的东西。

       执行引擎:在Java虚拟机规范中,执行引擎的行为使用指令集来定义。

       JVM的生命周期:java虚拟机就是用来执行java程序,一个java程序一个java虚拟机。程序开始执行的时候才运行,程序结束的时候他就停止。你再同一台机器上运行3个java程序,那么就有3个java虚拟机运行。Main()是程序的起点,他被执行的线程初始化为程序的初始线程。程序中其他的线程都由他来启动。

       Java线程分为两种。守护线程与普通线程。守护线程是jvm自己使用线程,他负责垃圾回收GC线程就是一个守护线程,java虚拟机上只要还有普通贤臣挂在运行,java虚拟机就不会停止,如果有足够权限,可以使用exit终止程序。
 

       由此可见,为什么java中会出现线程安全问题呢?就是因为静态对象以及对象属性等都是存放在方法区中,而方法区又是线程共享的区域,所以就会发生线程安全问题。

栈和堆中都是存放的什么?区别是什么?

       堆:所有new的对象,数组,存放的是对象,是栈内存中的具体引用,不会轻易被垃圾回收,会根据GC不定时的根据回收算法进行回收。       

       栈:基本数据,成员变量,变量有自己的作用域,一旦离开作用域,变量就会被释放,栈内存更新速度很快,因为局部变量的生命周期很短。

       总结:堆中保存的数据大多都是栈中数据的引用对象,目的就是为了节约空间,并且可以达到复用。因为多个栈中的数据可以同时引用堆中的数据,实际上栈中保存的就是堆内存中的一个地址。

       java八大基本数据类型:byte、short、int、long、char、float、double、boolean

我们都知道java的八基本数据类型都还有它的包装类型,那么基本数据类型和包装类型的区别是什么?

  1. 存放地不同:基本数据类型是在栈中,包装类型是在堆中。
  2. 占用内存大小不同:基本数据类型占用内存较小,包装类型因为是对象,所以占用内存较大。

总结:基本就是栈和堆的区别

基本类型和包装类型使用推荐:

       基本数据类型:临时变量,方法中什么的变量则为临时变量,或者使用次数较少的。

       包装数据类型:全局变量,经常被使用,因为对象会存放在堆中,不会立马被回收,则可以避免被重复创建而浪费时间以及空间。

另外如果有小伙伴需要详细了解jvm这里推荐一篇文章:JAVA后端知识点碎片化整理 基础篇(十二) 认识JVM

今天我们这里说一下JVM的知识,后续将会讲解到堆中的一个很重要的角色,垃圾回收者GC。

发布了25 篇原创文章 · 获赞 9 · 访问量 3049

猜你喜欢

转载自blog.csdn.net/qq_40053836/article/details/100825002
今日推荐