java时间类_百战程序员006 浅谈JVM如何运行Java程序

cdd72885df97e9ede19411ddded1046f.png

JVM如何运行Java程序

1.表面运行java程序步骤

1)首先创建一个.java结尾的文件,写上一段正确的代码

2)通过javac 文件绝对路径 去编译java文件 生成一个 文件名.class的字节码文件

3)通过java class字节码文件名去运行java程序

2. JVM运行原理

javac程序是一个java编译器,他讲java文件编译成class字节码文件,然后通过java命令吧字节码文件发送到虚拟机,虚拟机执行编译器放在class文件中的字节码。

1)JVM加载class文件的原理机制

5bd96e8dd535053f92bfc737fc11f381.png

2)JVM中类的装载器是由类加载器(CLassLoader)和它的子类来实现的,Java中的类加载器是一个重要的Java运行时系统组件,它负责在运行时查找和装入类文件中的类

由于Java的跨平台性,经过编译的Java源程序并不是一个可执行程序,而是一个或多个类文件。当Java程序需要使用某个类时,JVM会确保这个类已经被加载、连接(验证、准备和解析)和初始化

类的加载是把类的.class文件中的数据读入到内存中,通常是创建一个字符数组读入.class文件,然后产生与所加载类对应的Class对象。加载文成后,Class对象还不完整,所以此时的类还不可用。

当类被加载后就进入连接阶段,这一阶段包括验证、准备(为静态变量分配内存并设置默认的初始值)和解析(将符号引用替代为直接引用/地址)三个步骤。

最后JVM对类进行初始化,包括:1)如果类存在直接的父类并且那个类还没有被初始化,那么久先初始化父类;2)如果类中存在初始化语句,就一次执行这些初始化语句

类的加载是由类加载器完成的,类加载器包括:

跟加载器(BootStrap)、扩展加载器(Extension)、系统加载器(System)和用户自定义加载器(java.lang.ClassLoader的子类)。从java2(JDK1.2)开始,类加载过程采用了父亲委托机制(PDM,Parent Delegation Mechanism)。PDM更好多的保证了Java平台的安全性,在该机制中,JVM自带的Bootstrap是根加载器,其它的加载器都有仅有一个父类加载器。类的加载器首先请求父类加载器加载,父类加载器无能为力时才由子类加载器自行加载。JVM不会像Java程序提供对Bootstrap的引用

类加载器的说明:

Bootstrap:一般用本地代码实现,负责加载JVM类基础核心库(rt.jar)

Extension:从java.ext.dirs系统属性所执行的目录中的类加载库,他的父加载器是Bootstrap

System:又叫应用类加载器,其父类是Extension。它是最广泛的类加载器。它从环境变量classpath或者应用属性java.class.path所指定的目录中记载类,是用户自定义加载器的默认父加载器

(2)java的“一次编译到处运行”是如何做到的?

eaf7bb8cfaf1502a9c170a3dfd8bda75.png

虚拟机可以理解成为一个字节码为机器指令的CPU

对于不同的运行平台,有不同的虚拟机

Java虚拟机机制屏蔽了底层运行平台的差别,实现了“一次编译,随处运行”

垃圾回收机制GC(GarbageCollection)

GC是什么?为什么要有GC?

GC(GarabageCollection)是垃圾收集器的意思,内存处理是变成人员内容以出错的问题的地方,忘记或者是错误的内存回收会导致程序或系统的不稳定甚至崩溃,Java提供的GC功能可以自动检测对象是否超过作用域从而达到自动回收内存的目的,Java语言没有提供释放已分配内存你的显示操作方法。

Java程序员不用担心内存管理,因为垃圾收集器会自动进行管理,要请求垃圾收集器,可以调用下面的方法之一

Runtime.getRuntime().gc()

System.gc() //底层实际上就是调用了Runtime.getRuntime().gc()

但JVM可以屏蔽掉显示的垃圾回收调用。

垃圾回收可以有效的防止内存泄漏,有效的使用可以使用内存。垃圾回收器通常是作为一个单独的低优先级的线程运行,不可预知的情况下对内存中已经死亡或者长时间没有使用的对象进行清除和回收,程序员不能时时的调用垃圾回收器对某个对象或所有对象进行垃圾回收(程序员不能精确把控回收时间,调用System.gc()或Runtime.getRuntime().gc()这两个方法,就相当于通知了下GC,但GC什么时候来都是不一定的)

在Java诞生初期,垃圾回收是Java最大的亮点之一,因为服务器端的编程需要有效的防止内存泄漏的问题,然而时境过迁,如今Java的垃圾回收机制已经成为被诟病的东西。移动智能终端用户通常觉得IOS系统比Android系统有更好的用户体验,其中一个深层次的原因就是Android系统中垃圾回收的不可预知(绝大多数Android是由java写的)

垃圾回收机制也有很多种,包括:分代复制垃圾回收、标记垃圾回收、增量垃圾回收等。标准的Java对其进行了改进,采用“分代式垃圾收集”。这种方法会对Java对象的声明周期将堆内存划分为不同的区域,在来及收集过程中,可能会对对象移动到不同的区域:

伊旬园(Eden):这时对象最初诞生的区域,并且大多数对象来说,这时它们唯一存在

过的区域。

幸存者乐园(Survivor):从伊旬园幸存下来的对象会被挪到这里

终生颐养园(Tenured):这时足够老的幸存对象的归宿。年轻代收集(Minor-GC)过程是不会触及这个地方的。当年轻代收集不能把对象放进终身颐养园时,就会触发一次完全收集(Major-GC),这里可能还会牵扯到压缩,以便为大对象腾出足够的空间

JVM的符号引用和直接引用

在JVM中类加载过程中,在解析阶段,JAVA虚拟机会把类的二进制数据中的符号引用替换成直接引用

1. 符号引用(Symbolic References):

符号引用以一组符号来描述所引用的内容,符号可以是任何形式的字面量,只要使用时能够无歧义的定位到目标即可。列入在Class文件中它以CONSTANT_CLASS_info、CONSTANT_Fieldref_info、CONSTANT_Methodref_info等类型的常量出现。符号引用于虚拟机的内存布局无关,引用的目标并不一定加载到内存中。在Java中,诶一个java类将会编译成一个class文件。在编译时,java类并不知道所有引用的类的实际地址,因此只能使用符号引用来代替。比如org.simple.People类引用了org.simple.Language类,在编译时People类并不知道Language类的实际内存地址,因此只能使用符号org.simple.Language(假设是这个,当然实际中是由类似于CONSTANT_Class_info的常量来表示的)来表示Language类的地址。各种虚拟机实现的内存布局可能有所不同,但是他们能接受的符号引用都是一致的,因为符号引用的字面量形式确定在Java虚拟机规范的Class文件格式中

2. 直接引用

直接引用可以使

1)直接指向目标的指针(比如,指向类型【Class】对象、类变量、类方法的直接引用可能是指向方法区的指针)

2)相对偏移量(比如,指向实例变量、实例方法的直接引用都是偏移量)

3)一个能间接定位到目标的句柄

直接引用是和虚拟机的布局相关的,同一符号引用在不同的虚拟机实例上翻译出来的直接引用一般不会相同,如果有了直接引用,那引用的目标必定已经被加载到内存中去了

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值