关于JVM运行机制的一些理解

学习java有一段时间,一直挺好奇java底层是怎么实现的,以及java语言特性的优点。因此自己作下总结,如果本文有错误处请各位看官批评指出,我要及时修正我的一些理解。

跨平台

首先对于java,之所以能够跨平台运行,依赖于底层的jvm实现机制。所有的代码写完后,都会翻译成jvm所能识别的字节进行存取。jvm编码都是用Unicode。当需要加载的时候,就会把字节转为平台所能懂得语言。因此一个java能够在不同平台运行,只需要配置好jvm,将你的java文件拿到不同平台运行就可以了。

垃圾回收

同时,jvm有垃圾回收机制,不像c++一样用指针,进行显示回收,容易造成内存泄露。jvm会判断对象是否存活对对象进行回收。主要有两种方法:可达性分析和引用计数算法。说下两者区别:

1. 可达性分析:通过一些GC Roots的对象作为索引,向下搜索,搜索所有走过的路径称为“引用链”。当对象没有被任何引用链所连接时,则这个对象时不可到达的。就被判断为是可以回收的对象。

2. 引用计数算法:给每个对象添加一个引用计数器。被引用的时候,计数器加一;当不被引用的时候,计数器减一。当计数器为0时,表示可以被回收。这个方法虽然简单易懂,但是无法解决对象间相互引用的情况。

内存分配

JVM在类加载时会把内存分配成各个区域。这部分区域属于运行时数据区。区域主要分为5个部分,分别为:程序计数区,JAVA虚拟机栈,本地方法区,JAVA堆,方法区。以下谈谈我对这几个区域的理解

线程私有的

1. 程序计数区:JVM实现多线程,是通过线程轮流切换并分配处理器。一个处理器只会执行一个线程的指令。为了让线程能够安全顺利地执行,为每个线程都添加了私有的程序计数器。(这是JVM上唯一一个不会发生OOM异常的区域)

2. JAVA虚拟机栈:它和JAVA堆得区别主要是存储一些基本数据类型和对象的引用。它是为JVM提供JAVA方法。一个方法从调用到执行结束,就对应了一个栈帧在虚拟机中入栈和出栈的整个过程。

3. 本地方法区:同JAVA虚拟机栈类似,主要是提供JVM的Native方法。

所有线程所共有的数据区

1. JAVA堆:new出的对象都是在JAVA堆上,当创建一个对象时,就会在堆上创建相应的java.lang.class文件,在方法区上保存相应类的数据结构,相当于JAVA堆提供了类在方法区上的接口。这部分区域也是GC回收的主要区域。内存分配是不连续的。

2. 方法区:同样是不连续的,存储了类里的常量,静态变量,编译后的代码,被虚拟机加载的类信息等。

值得注意的是,JDK1.7及之后的版本,JVM已经将运行时常量池从方法区中移了出来,在JAVA堆上开辟了一块区域存放运行时常量池。同时JAVA8的到来,也取消了老年代,为其开辟了新的空间成为元空间。具体大家可以百度搜索一下。

JVM类加载的过程

加载过程包括三个部分:

1. 装载

将class文件字节码内容加载到内存,即翻译成jvm能看懂的语言。将类的静态变量、类信息放置在运行时数据区的方法区内,在堆上创建java.lang.class对象,提供方法区的数据入口。

2. 连接

连接包含验证、准备、解析

其中验证是指类的加载信息完全符合JVM规范;

准备是指为static成员变量分配内存,初始化值,这些值是在方法区中进行分配;

解析是指常量池的符号引用替换成字节引用;

3. 初始化

初始化类是通过初始化类的构造器的方法,如果该类有父类,则先初始化该父类构造器方法。



以上,是我关于JVM运行机制的一些理解,欢迎补充或批评指导!

  • 0
    点赞
  • 1
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值