Java程序从创建到运行要经过两个大步骤

1:源文件(.java)由编译器编译成字节码ByteCode(.class)

2:字节码由Java虚拟机解释并运行

源文件编译成字节码,主要分成两个部分:

1:常量池:所有的Token(类名、成员变量名等)、符号的引用(方法引用、成员变量应用等)

2:方法字节码:各个类中的各个方法的字节码

字节码由Java虚拟机解析运行分成两个部分:

1:类加载

2:类的执行

程序运行的详细步骤:(运行一个对象下的方法内部的细节)

Animal.java

public class Animal {

public String name;

public Animal(String name) {

this.name = name;

}

public void printName() {

System.out.println("Animal ["+name+"]");

}

}

MainApp.java

public class MainApp {

public static void main(String[] args) {

Animal animal = new Animal("Puppy");

animal.printName();

}

}

下面是程序运行的详细步骤:

1. 在编译好java程序得到MainApp.class文件后,执行MainApp。

系统就会启动一个jvm进程,jvm进程从classpath路径中找到一个名为MainApp.class的二进制文件,将MainApp的类信息加载到运行时数据区的方法区内,这个过程叫做MainApp类的加载。

2. JVM找到AppMain的主函数入口,开始执行main函数。

3. main函数的第一条命令是Animal animal = new Animal("Puppy");

就是让JVM创建一个Animal对象,但是这时候方法区中没有Animal类的信息,所以JVM马上加载Animal类,把Animal类的类型信息放到方法区中。

4. 加载完Animal类之后,Java虚拟机做的第一件事情就是在堆区中为一个新的Animal实例分配内存, 然后调用构造函数初始化Animal实例,这个Animal实例持有着指向方法区的Animal类的类型信息(其中包含有方法表,java动态绑定的底层实现)的引用。

5. 当使用animal.printName()的时候,JVM根据animal引用找到Animal对象,然后根据Animal对象持有的引用定位到方法区中Animal类的类型信息的方法表,获得printName()函数的字节码的地址。

6. 开始运行printName()函数。

类加载

类的加载指的是将类的.class文件中的二进制数据读入到内存中,将其放在运行时数据区的方法区内,然后在堆区创建一个java.lang.Class对象,用来封装类在方法区内的数据结构。

类的加载的最终产品是位于堆区中的Class对象,Class对象封装了类在方法区内的数据结构,并且向Java程序员提供了访问方法区内的数据结构的接口

类加载机制的内部细节

从类被加载到虚拟机内存中开始,到卸御出内存为止,它的整个生命周期分为7个阶段:

加载(Loading)、验证(Verification)、准备(Preparation)、解析(Resolution)、初始化(Initialization)、使用(Using)、卸御(Unloading)。其中验证、准备、解析三个部分统称为连接。 7个阶段发生的顺序如下:

加载

1、将class文件加载在内存中。

2、将静态数据结构(数据存在于class文件的结构)转化成方法区中运行时的数据结构。

注意:方法区中如果出现OOM,那么多半是因为加载的依赖太多

3、在堆中生成一个代表这个类的java.lang.Class对象,作为数据访问的入口

连接

1、验证:确保加载的类符合JVM规范与安全。保证被校验类的方法在运行时不会做出危害虚拟机安全的事件

2、准备:为static变量在方法区中分配空间,设置变量的初始值。例如static int a=3,在此阶段会a被初始化为0;

注意:准备阶段,只设置类中的静态变量(方法区中),不包括实例变量(堆内存中),实例变量是在对象初始化的时候分配值的

3、解析:

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

符号引用:简单的理解就是字符串,比如引用一个类,java.util.ArrayList 这就是一个符号引用

直接引用:指针或者地址偏移量。引用对象一定在内存(已经加载)。

初始化

初始化是类加载的最后阶段,初始化阶段是执行类构造器()方法。在类构造器方法中,它将**由编译器自动收集类中的所有类变量的赋值动作**()和静态变量与静态语句块static{}合并

**初始化,为类的静态变量赋予正确的初始值**

使用、卸载

使用:正常使用

卸载:GC把无用的对象从内存中卸载

类加载器

其中加载、验证、准备、解析、初始化构成了类加载的的整个过程;

但是类的加载是需要通过类加载器来实现的

1)Bootstrap ClassLoader

负责加载$JAVA_HOME中jre/lib/rt.jar里所有的 class,由 C++ 实现,不是 ClassLoader 子类。

2)Extension ClassLoader

负责加载Java平台中扩展功能的一些 jar 包,包括$JAVA_HOME中jre/lib/*.jar或-Djava.ext.dirs指定目录下的 jar 包。

3)App ClassLoader

负责加载 classpath 中指定的 jar 包及目录中 class。

4)Custom ClassLoader

属于应用程序根据自身需要自定义的 ClassLoader,如 Tomcat、jboss 都会根据 J2EE 规范自行实现 ClassLoader。

加载过程中会先检查类是否被已加载,检查顺序是自底向上,从 Custom ClassLoader 到 BootStrap ClassLoader 逐层检查,只要某个 Classloader 已加载就视为已加载此类,保证此类只所有 ClassLoader 加载一次。而加载的顺序是自顶向下,也就是由上层来逐层尝试加载此类。

通过代码验证类加载器模型:

public class ClassLoaderTest {

public static void main(String[] args) {

ClassLoader loader = Thread.currentThread().getContextClassLoader();

System.out.println(loader);

System.out.println(loader.getParent());

System.out.println(loader.getParent().getParent());

}

}

在获取ExtClassLoader的父loader的时候出现了null,这是因为Bootstrap Loader(引导类加载器)是用C++语言实现的,找不到一个确定的返回父Loader的方式,于是就返回null

java 程序编译和运行过程

java整个编译以及运行的过程相当繁琐,我就举一个简单的例子说明: Java程序从源文件创建到程序运行要经过两大步骤: 1.源文件由编译器编译成字节码(ByteCode): 2.字节码由java虚拟机 ...

Java程序编译和运行的过程

Java整个编译以及运行的过程相当繁琐,本文通过一个简单的程序来简单的说明整个流程. 如下图,Java程序从源文件创建到程序运行要经过两大步骤:1.源文件由编译器编译成字节码(ByteCode)  2 ...

Java程序编译和运行的过程【转】

转自:http://www.360doc.com/content/14/0218/23/9440338_353675002.shtml Java整个编译以及运行的过程相当繁琐,本文通过一个简单的程序来 ...

.NET概念:.NET程序编译和运行

.NET概念:.NET程序编译和运行 分类: c#程序设计 2012-02-29 15:46 3001人阅读 评论(2) 收藏 举报 .net编译器语言microsoftassemblyvb.net ...

Java编辑编译及运行环境

Java编辑编译及运行环境 Microsoft Windows 编辑工具 EditPlus JDK JDK(Java Development Kit,Java开发工具包)安装JDK之后,其中bin文件 ...

Java高编译低运行错误(ConcurrentHashMap.keySet)

Java高编译低运行错误(ConcurrentHashMap.keySet) 调了一天: https://www.jianshu.com/p/f4996b1ccf2f

.NET程序编译和运行

一次面试的时候遇到的一道题目,简要说明.NET的编译过程,在网上看了很多资料,简单总结如下: 1.一般的编译过程 通常高级语言的程序编译过程是:首先写好的程序是源代码,然后编译器编译为本地机器语言,最 ...

java程序可以跨平台运行的原因

java有虚拟机(JVM),JAVA程序不是直接在电脑上运行的,是在虚拟机上进行的,每个系统平台都是有自己的虚拟机(JVM),所以JAVA语言能跨平台. 1, java代码不是直接运行在CPU上,而是 ...

java文件编译及运行

1 配置环境变量 使用鼠标右击“我的电脑”->属性->高级->环境变量 系统变量->新建->变量名:JAVA_HOME 变量值:C:\Program Files (x86 ...

随机推荐

c#导出bugfree3.0的数据到禅道

环境:vs2012MVC4项目,mysql server5.6 准备:bugfree的数据库导出后.sql文件,禅道7.1的数据库文件 基本过程:这是个笨办法,也没有优化过代码,导入数据时候比较慢.禅 ...

用Python向MySQL数据库插入数据

最近一直在学习MySQL数据库,很感兴趣.这次我做了一个简单的尝试,使用Python3.4与MySQL数据库进行交互,将一份从雪球网上下载的某股票数据上传至MySQL数据库.仅为初学者提供参考,高手请 ...

ruby Errors & Exceptions

When you first started coding, errors were probably the last thing you wanted to see. After all, it’ ...

【Shell脚本学习4】几种常见的Shell

上面提到过,Shell是一种脚本语言,那么,就必须有解释器来执行这些脚本. Unix/Linux上常见的Shell脚本解释器有bash.sh.csh.ksh等,习惯上把它们称作一种Shell.我们常说 ...

servlet跳转jsp

ackage com.monkey.servlet; import javax.servlet.*; import javax.servlet.http.*; import java.io.*; im ...

关于iOS应用管理之九宫格的坐标计算以及与UIScrollView的结合

关于九宫格的布局以及坐标的计算,对于大多数的iOS初学者甚至有一定能力的学者来说都是一大难题,在此写者通过自己的开发经验以及多次应用,把自己的所学所得分享给大家,就通过应用管理来进行浅谈一二.     ...

RMSE、RMS、标准差

1.均方根误差,它是观测值与真值偏差的平方和观测次数n比值的平方根,在实际测量中,观测次数n总是有限的,真值只能用最可信赖(最佳)值来代替.方根误差对一组测量中的特大或特小误差反映非常敏感,所以,均方 ...

【开发技术】对文件内容进行加密-java

http://hi.baidu.com/java0804ms/item/111ea834fbd4d2f596f88d5a 实现效果:对文件内容进行加密,使之直接打开成为乱码,不以明文显示 实现步骤:1 ...

python3随机数函数

随机数函数 choice(seq) 从序列的元素中随机挑选一个元素,比如random.choice(range(10)),从0到9中随机挑选一个整数. randrange ([start,] stop ...

Spring系列__01HelloWorld

Spring作为一款成熟的Java框架,其优点和意义不用我多说,可以参考:https://m.w3cschool.cn/wkspring/pesy1icl.html 今天开始写一下Spring家族的总 ...

Java在加载阶段会加载依赖吗,Java程序编译和运行过程之 一个对象的生命之旅(类加载和类加载器)...相关推荐

  1. 编译运行一个java程序_如何从另一个Java程序编译和运行Java程序

    编译运行一个java程序 Have you ever thought if it's possible to compile and run a java program from another j ...

  2. java 程序编译和运行的过程

    Java整个编译以及运行的过程相当繁琐,本文通过一个简单的程序来简单的说明整个流程. 如下图,Java程序从源文件创建到程序运行要经过两大步骤:1.源文件由编译器编译成字节码(ByteCode)  2 ...

  3. Java程序编译和运行的过程

    Java整个编译以及运行的过程相当繁琐,本文通过一个简单的程序来简单的说明整个流程. 如下图,Java程序从源文件创建到程序运行要经过两大步骤:1.源文件由编译器编译成字节码(ByteCode)  2 ...

  4. 使用命令行编译、运行Java程序

    我们一般都是通过IDE(如Eclipse.Intellij Idea,STS等)来开发,调试java项目. 在不借助IDE的情况下,如何编译.运行Java程序. 使用javac 命令,可以通过只敲击j ...

  5. java 调用笔记本摄像头拍照_教程:如何使用Java和C++在应用程序中实现面部识别

    全文共8470字,预计学习时长25分钟 来源:xaecong HOG:梯度方向直方图(histogram of orientedgradients)是一种图片描述符格式,它能够汇总图像(例如人脸)的主 ...

  6. java编译不报错但运行啥都没_java编译时与运行时概念与实例详解

    java编译时与运行时概念与实例详解 发布于 2020-7-29| 复制链接 本篇文章通过实例对 java程序编译时与运行时进行了详解,需要的朋友可以参考下 Java编译时与运行时很重要的概念,但是一 ...

  7. 上海市计算机二级java程序设计真题_上海市计算机等级考试二级java程序设计.doc...

    上海市计算机等级考试二级java程序设计.doc 程序填空题第1题.程序实现青年歌手比赛的评分计算.其计算方法是将十位评委的个人评分去掉其中的最高分和最低分,然后输出其余评委评分的平均值作为该歌手的最 ...

  8. Java常见面试题之类的加载过程

    程序员看似光鲜的就业前景面前,逃不过的是层层的面试,想要进前沿的大公司没有个五六七八面,是不可能滴!而找工作的首个关卡就是笔试,想要获得高薪工作的小伙伴,先刷一波面试题吧! 类加载过程主要包含加载.验 ...

  9. 描述一下JAVA的加载过程_JVM源码分析之Java类的加载过程

    简书 占小狼 转载请注明原创出处,谢谢! 趁着年轻,多学习 背景 最近对Java细节的底层实现比较感兴趣,比如Java类文件是如何加载到虚拟机的,类对象和方法是以什么数据结构存在于虚拟机中?虚方法.实 ...

最新文章

  1. [数分提高]2014-2015-2第4教学周第2次课
  2. “领悟”的价值是什么?思维能力训练问答
  3. [转] JSON转换
  4. 解决Maven报Plugin execution not covered by lifecycle configuration (转载)
  5. linux 网卡驱动分析,LINUX_网卡驱动分析
  6. JavaScript高级day02-AM【函数的prototype、显式原型与隐式原型、原型链】
  7. HTML的a标签置灰不可点击
  8. php 下拉菜单 多个值,PHP,而foreach下拉菜单在所有下拉菜单中都具有相同的选定值...
  9. 第33课 打擂台 《小学生C++趣味编程》
  10. overridePendingTransition介绍
  11. 【codevs1041NOIP01TG】Car的旅行路线,最短路中的数学题
  12. Python爬取你好李焕英豆瓣短评并利用stylecloud制作更酷炫的词云图
  13. Python开发过程中错误解决记录【持续更新记录,欢迎交流】
  14. 批量部署windows和linux系统,使用Cobbler批量部署Linux和Windows:Windows系统批量安装(三)...
  15. 什么软件可以修改PDF,PDF如何添加页码
  16. cobar mysql_mysql分布式中间件cobar
  17. 北京小米Java有笔试吗_小米校招笔试题(java)
  18. angular directive 入门
  19. CIsco思科三层交换配置DHCP,客户端动态获取
  20. Android Studio 使用记录

热门文章

  1. 理解神经网络函数高频成分的收敛率界限
  2. CVPR 2020 | 自适应聚合网络AANet:更高效的立体匹配
  3. BERT+知识图谱:北大-腾讯联合推出知识赋能的K-BERT模型
  4. F-Principle:初探深度学习在计算数学的应用
  5. 重磅公开课推荐 | 如何搭建聊天机器人:技术架构剖析
  6. 牛客网 最短路 Floyd算法 Dijkstra算法 Java大数
  7. Pinpoint【环境搭建 01】JDK\HBase\Pinpoint Collector+Web 最新版 2.3.3 安装配置运行验证及脚本文件分享(避坑指南捷径指北)
  8. nginx反向代理和负载均衡
  9. time库python_Python的time库的一些简单函数以及用法
  10. pandas 索引_Pandas学习笔记03数据清洗(通过索引选择数据)