一、安装环境

大家在开发Java的时候,首先回装一个java的开发环境,一个JDK(也包含了JRE),然后设置环境变量,这个过程我就不细说了,大家装完后有没有发现,在装完这个环境的同时在安装JRE,在JDK的文件夹下还有一个jre文件夹,说这个有什么意思呢,首先我们要理解JDK和JRE的区别。

JDK:开发环境。

JRE:运行环境。

就是这么简单,那么是怎么运行起来的呢,我们一定经历过这样的一个阶段,在黑乎乎的窗口敲下下面的代码:

javac hello.java

这个过程就是江hello.java这个程序编译成二进制序列的.class文件,它用的就是JDK中的工具。

这个编译后的.class文件是给JRE看的,因为也只有它能看的懂了。它拿他只需要负责其运行就好。

说这个和运行有什么关系?JRE下包含了一个java运行的核心JVM(java虚拟机),JVM是java的核心,也是运行的核心。

二、java的运行

java的运行,首先,计算机会启动一个进程(注意:线程和进程的区别),运行JVM,所有java的线程都在这个JVM进程中执行,不断这个java程序有多少的线程。但是这个JVM也有其生命周期,总有一个程序的开始Main()来启动整个程序的线程,一般称为普通线程,JVM也有自己的线程,一般称为守护线程。当JVM中还有普通线程的时候,它的生命就一直持续,那么什么时候这个JVM会死亡呢?出现下面几种情况下,它就会死亡:

1、程序正常运行结束。

2、程序运行到System.exit()或者Runtime.getRuntime().exit()代码的时候结束

3、非法强制关闭JVM

4、遇到程序中未捕捉到的异常或者错误

关于JVM的介绍网上很多,我这里给出一个链接,大家可以看看:http://www.importnew.com/17770.html

2.1、类的加载

2.1.1 什么是类的加载

当程序再运行的过程中,会调用某个类,当这个类没有加载到内存的时候,那么系统做的第一步就是加载这个类到内存,说的直白点,就是读取我们编译好的.class文件到内存,但是这个过程中有一个重要的环节,就是在加载这个.class文件的时候也会创建一个一个对象java.lang.Class对象,和这个文件所对应的具体什么对象无关,也就是说,无论加载一个什么类,它都会为这个类创建一个java.lang.Class对象,可以这么理解,我们所谓的类,也是一个对象,不过我们的类是Class的实例,那么这个Class是什么对象,我从文档中,找到这样的一个介绍:

这里有一句话:Class 对象是在加载类时由 Java 虚拟机以及通过调用类加载器中的 defineClass 方法自动构造的。

这里面也透露了一个信息:类的加载是通过类加载器实现的。

2.1.2、类加载来源

类的加载器通过哪些渠道加载.class文件?有下面几个渠道:

1、本地的.class文件

2、JAR包中的.class文件

3、通过网络加载.class文件

在上面给的连接中,也对其做了一些介绍,JVM中,在启动的时候,会形成三个类加载器组成的出事类加载器:

1、Bootstrap ClassLoader:根类加载器(bootstrap 加载器负责载入基础的 Java API,比如包含 rt.jar。它只加载拥有较高信任级别的启动路径下找到的类,因此跳过了很多普通类需要做的校验工作。)

2、Extension ClassLoader:扩展类加载器(加载了标准 Java 扩展 API 中的类,比如 security 的扩展函数。)

3、System ClassLoader:系统类加载器(应用的默认类加载器,比如从 classpath 中加载应用类。)

4、用户自定义ClassLoader:用户自定义加载器

也许会很好奇,这些究竟会加载哪些包:

Bootstrap ClassLoader:%JAVA_HOME%\jre\lib文件夹下的一些包

Extension ClassLoader:%JAVA_HOME%\jre\lib\ext文件夹下的一些包

System ClassLoader:命令中-classpath选项或者java.class.path系统属性,或者CLASSPATH环境变量中定义的JAR包和类的路径。

2.1.3、类加载器执行顺序和类的加载流程

类的加载器的使用顺序如下:

一个类的加载的时候会先检查缓存中是否已经加载过,怎么识别呢,java关于类是否加载过的主要三个参数是,类名,包名 ,类加载器,三个元素组成了这个类加载的“id”,唯一的id,如果加载过了,就会直接加载,如果没有加载过会先让父元素先加载,如果父元素也无法加载的时候再阶级而下的加载器进行加载,如果未找到这个类,就会排除ClassNotFFoundException异常。

类的加载流程如下:

2.1.4、用户类加载器

在上面我们提到了用户类加载器,一般情况下用户不需要建立自己的加载器,但是在一些特殊情况下,我们也可以创建自己的类加载器,只要继承java.lang.Class对象,从之前的介绍可以看出这个类是一个抽象类。

我们主要介绍下这个类中的以下重要的方法:

1、loadClass(String name,boolean resolve):使用指定二进制名称加载类,name二进制名称,resolve是否分析这个类(关于分析后面介绍)

2、loadClass(String name):和上面的作用相同,相当于loadClass(name,false);

3、findClass(String name):使用指定二进制名查找类。

4、findLoadedClass(String name):如果 Java 虚拟机已将此加载器记录为具有给定二进制名称的某个类的启动加载器,则返回该二进制名称的类。

在我们创建用户类加载器的时候,最好是重写findClass方法,这个方法的执行的顺序如下:

1、先执行findLoadedClass(String)来检查是否已经加载了这个类,如果加载了直接返回这个类。

2、在父类加载器上调用loadClass方法,如果父类加载器为null,则使用根类加载器来加载。

3、调用findClass(String)查找类

所以重写findClass方法可以避免覆盖默认类加载器的父类委托,缓冲机制两种策略。如果重写loadClass方法,实现的逻辑比较复杂。

2.2、类的链接

类的链接包含了三块,具体详情,看这一块(http://blog.csdn.net/jintao_ma/article/details/51353453):

1、验证

验证是链接阶段的第一步,这一步主要的目的是确保class文件的字节流中包含的信息符合当前虚拟机的要求,并且不会危害虚拟机自身安全。
验证阶段主要包括四个检验过程:文件格式验证、元数据验证、字节码验证和符号引用验证。

2、准备:

类准备阶段扶着为类的静态属性分配内存,并设置默认初始值(注意:是默认初始值,不是初始值)。

3、解析:

将类的二进制数据中的符号引用直接替换成直接引用。

2.3、类的初始化

类的初始化,主要是为类的静态属性赋予初始值。通常会在两个地方进行初始化赋值,一个是静态变量直接赋予初始化值,一个是在静态初始化块中进行初始化赋值。

java运行过程的更多相关文章

  1. 基础知识《零》---Java程序运行机制及运行过程

    Java运行机制 Java虚拟机(Java Virtual Machine):Java虚拟机可以理解成一个以字节码为机器指令的CPU:对于不同的运行平台,有不同的虚拟机:Java虚拟机机制屏蔽了底层运 ...

  2. JAVA - JAVA编译运行过程

    Java编译原理 *.java→*.class→机器码 java编译器 (编译) → 虚拟机(解释执行) →  解释器(翻译) → 机器码 1.Java编译过程与c/c++编译过程不同 Java编译程 ...

  3. Windows7下的Java运行环境搭建过程图解

    第一步:下载JDK 地址:http://www.oracle.com/technetwork/java/javase/downloads/index-jsp-138363.html,(由于Sun于20 ...

  4. java入门(1) 程序运行机制及运行过程

    首先我们来看一下java程序在底层是怎么工作的: JAVA有两种核心机制: Java虚拟机(Java Virtual Machine): 1.java虚拟机可以理解成一个以字节码为机器指令的CPU. ...

  5. java 程序运行过程 简介

    这里的Java程序运行过程,是指我们编译好代码之后,在命令行开始执行java xxx命令,到java程序开始执行起来的这一过程,我们称其为运行时. 第一步,操作系统解析我们输入的java xxx命令, ...

  6. Java内存管理-程序运行过程(一)

    勿在流沙住高台,出来混迟早要还的. 做一个积极的人 编码.改bug.提升自己 我有一个乐园,面向编程,春暖花开! 相信在做Java开发的伙伴一定知道 JVM(Java Virtual Machine( ...

  7. 详细理解Java虚拟机的运行过程

    基本概述: Java虚拟机简称JVM,是JRE中的一部分,也是Java程序运行的最关键的部分.完整的Java运行流程大致包括编译.java文件形成.class文件,然后根据.class文件的内容进行一 ...

  8. Java基础之Java编译运行过程

    Java编译运行过程 程序员所编写的是以.java为后缀的文件,此文件操作系统不能正确识别,因此,首先要经过编译,生成所谓的字节码文件(.class),而字节码文件需要JVM来提供运行环境的支持. J ...

  9. Java程序员必了解的JVM原理以及虚拟机的运行过程

    JVM概念 虚拟机:指以软件的方式模拟具有完整硬件,VM概念 虚拟机:指以软件的方式模拟具有完整硬件系统功能.运行在一个完全隔离环境中的完整计算机系统 ,是物理机的软件实现.常用的虚拟机有VMWare ...

随机推荐

  1. 使用ansible编译安装运维工具tmux

    实验系统:CentOS 6.6_x86_64 实验前提:提前准备好编译环境,防火墙和selinux都关闭 软件介绍:tmux是一个优秀的终端复用软件,类似GNU Screen,但来自于OpenBSD, ...

  2. awk-笔记

    语法形式: awk [options] 'script' var=value file1 [file...] awk [options] -f scriptfile var=value file [f ...

  3. [django]Django站点admin支持中文显示和输入设置

    正文: Django站点admin支持中文输入设置,操作如下: 1 需要确定的你的数据库的client客户端和服务端的编码设置为utf-8,如果不是,请将其设置成utf-8编码,我采用mysql,详情 ...

  4. Redis学习总结

    Redis是一个开源的使用ANSI C语言编写.支持网络.可基于内存亦可持久化的日志型.Key-Value数据库,并提供多种语言的API,其实当前最热门的NoSQL数据库之一,NoSQL还包括了Mem ...

  5. Markdown 完全指南

    概述 Markdown 是一种用于网络文本书写的轻量级标记语言,广泛用于个人 blog.github.wiki 中.其实浏览器并不能识别 Markdown 的语法,但许多 blog.wiki 平台以及 ...

  6. 【每日一linux命令6】命令中的命令

    许多命令在执行后,会进入该命令的操作模式,如 fdisk.pine.top 等,进入后我们必须要使用该 命令中的命令,才能正确执行:而一般要退出该命令,可以输入 exit.q.quit 或是按[Ctr ...

  7. quartz-1.8.5 Demo

    最近在研究Spring中的定时任务功能,最好的办法当然是使用Quartz来实现.对于一个新手来说,花了我不少时间,这里我写个笔记,给大家参考. 我使用的是Maven来管理项目,需要的Jar包我给大家贴 ...

  8. J2EE,J2SE,J2ME,JDK,SDK,JRE,JVM区别

    转自:http://www.metsky.com/archives/547.html 一.J2EE.J2SE.J2ME区别 J2EE——全称Java 2 Enterprise Edition,是Jav ...

  9. [译]Spring构建微服务

    此文为译文,原文地址 介绍 本文通过一个使用Spring.Spring Boot和Spring Cloud的小例子来说明如何构建微服务系统. 我们可以通过数个微服务组合成一个大型系统. 我们可以想象下 ...

  10. 【jQuery】 jQuery上下飘动效果

    jQuery实现图片上下飘动效果 function moveRocket() { $(".smallShip") //2000毫秒内top = top + 60: .animate ...