一、Java程序是如何运行的

Java中有一个虚拟机的概念,就是在机器和编译程序之间多了一层抽象的虚拟的机器,这个虚拟机在各个平台上都提供给编译程序一个共同的接口(这样就可以跨平台了吧?),编译程序只需要面向虚拟机,生成虚拟机能理解的代码,然后由解释器来将虚拟机代码转换为特定系统的机器码。这种让虚拟机理解的代码叫字节码

JVM就是Java虚拟机的英文缩写,全名是Java VirtualMachine,它是怎么工作的呢?我们先写一串代码,然后介绍这个代码的运行过程。

public class Main {

    private static int size=1;

    public static void main(String args[]) {

        User u = new User();

        u.setName("Realsky");

        u.setPwd("110");

        String name = u.getName();

        String pwd = u.getPwd();

        u = null;

    }

}

class User {

    private String name;

    private String pwd;

    public String getName() {

        return name;

    }

    public void setName(String name) {

        this.name = name;

    }

    public String getPwd() {

        return pwd;

    }

    public void setPwd(String pwd) {

        this.pwd = pwd;

    }

}

装载

JVM装载指定的class文件,最终形成这个class类的实例对象。

JVM使用类装载器定位到相应的class文件,然后读取这个class文件(一个线性二进制工作流),把它传给JVM。然后JVM提取其中的类型信息,比如类的类名,方法名,变量名,修饰符,方法的返回类型等等。还要初始化常量池,里面保存了各种类型的所有常量。之后将这些东西放到一个叫方法区的地方,形成class类的实例,这个实例存放在内存的堆区,它成为java程序和内部数据结构之间的接口,程序要访问该类型的信息,就调用该类型对应的class实例对象的方法。

比如:装载Main类,读取Main类的class文件,生成对应的java.lang.Class类的实例,读取其中的类型信息,比如修饰符private,public,static,变量size,name,pwd,User共同构成了这个类的常量池,将这些信息保存在方法区。

连接

验证类,保证这个类是没有错误的。

确定类中类型符合Java语义,比如final类不能有子类,final方法不能被覆盖,等等。之后为类变量分配内存,设置默认值。最终在类型的常量类中寻找类、接口、字段和方法的复合引用替换成直接引用的过程。

比如:连接Main类,JVM为size分配内存,并设默认值0,找到常量池中User类的引用,如果User类还没有装载就装载并连接这个类,然后将常量池中对User类的引用替换为直接引用,这个时候User类还没有初始化,因为还没有用到它。

初始化

初始化一些静态变量,让这个类可以跑起来。

可能会调用()方法(这个方法只能由JVM来调用)来初始化该类的静态变量,调用这个方法之前,要确认超类的()方法已经调用完毕。

比如:初始化Main类,JVM将Main类的静态变量赋值为1.

使用

User u = new User(); 

创建一个User类实例,实际上是通过这个类的class实例实例化的,方法:

User u=(User)Class.forName("User").newInstance();


u.setName("RealSky"); u.setPwd("110");

调用类的方法, 为该类的变量复制。JVM的调用过程是,通过方法区找到这个方法,利用class实例的如下方法调用:

Class.forName("User").getMethod("setName").invoke(u,"RealSky");


String name = u.getName(); String pwd = u.getPwd();

和上一步类似,区别就是这个赋值给了其他变量,这个变量和实例对象一样,保存在堆区。而我们也发现了,class实例的作用就是起到一个中间作用,将程序中的调用放映到堆区上数据的变化。


u = null;

触发JVM的垃圾回收机制,使用完这个命令,User实例就没有被引用了,JVM就会回收这个实例。

©著作权归作者所有,转载或内容合作请联系作者
  • 序言:七十年代末,一起剥皮案震惊了整个滨河市,随后出现的几起案子,更是在滨河造成了极大的恐慌,老刑警刘岩,带你破解...
    沈念sama阅读 204,793评论 6 478
  • 序言:滨河连续发生了三起死亡事件,死亡现场离奇诡异,居然都是意外死亡,警方通过查阅死者的电脑和手机,发现死者居然都...
    沈念sama阅读 87,567评论 2 381
  • 文/潘晓璐 我一进店门,熙熙楼的掌柜王于贵愁眉苦脸地迎上来,“玉大人,你说我怎么就摊上这事。” “怎么了?”我有些...
    开封第一讲书人阅读 151,342评论 0 338
  • 文/不坏的土叔 我叫张陵,是天一观的道长。 经常有香客问我,道长,这世上最难降的妖魔是什么? 我笑而不...
    开封第一讲书人阅读 54,825评论 1 277
  • 正文 为了忘掉前任,我火速办了婚礼,结果婚礼上,老公的妹妹穿的比我还像新娘。我一直安慰自己,他们只是感情好,可当我...
    茶点故事阅读 63,814评论 5 368
  • 文/花漫 我一把揭开白布。 她就那样静静地躺着,像睡着了一般。 火红的嫁衣衬着肌肤如雪。 梳的纹丝不乱的头发上,一...
    开封第一讲书人阅读 48,680评论 1 281
  • 那天,我揣着相机与录音,去河边找鬼。 笑死,一个胖子当着我的面吹牛,可吹牛的内容都是我干的。 我是一名探鬼主播,决...
    沈念sama阅读 38,033评论 3 399
  • 文/苍兰香墨 我猛地睁开眼,长吁一口气:“原来是场噩梦啊……” “哼!你这毒妇竟也来了?” 一声冷哼从身侧响起,我...
    开封第一讲书人阅读 36,687评论 0 258
  • 序言:老挝万荣一对情侣失踪,失踪者是张志新(化名)和其女友刘颖,没想到半个月后,有当地人在树林里发现了一具尸体,经...
    沈念sama阅读 42,175评论 1 300
  • 正文 独居荒郊野岭守林人离奇死亡,尸身上长有42处带血的脓包…… 初始之章·张勋 以下内容为张勋视角 年9月15日...
    茶点故事阅读 35,668评论 2 321
  • 正文 我和宋清朗相恋三年,在试婚纱的时候发现自己被绿了。 大学时的朋友给我发了我未婚夫和他白月光在一起吃饭的照片。...
    茶点故事阅读 37,775评论 1 332
  • 序言:一个原本活蹦乱跳的男人离奇死亡,死状恐怖,灵堂内的尸体忽然破棺而出,到底是诈尸还是另有隐情,我是刑警宁泽,带...
    沈念sama阅读 33,419评论 4 321
  • 正文 年R本政府宣布,位于F岛的核电站,受9级特大地震影响,放射性物质发生泄漏。R本人自食恶果不足惜,却给世界环境...
    茶点故事阅读 39,020评论 3 307
  • 文/蒙蒙 一、第九天 我趴在偏房一处隐蔽的房顶上张望。 院中可真热闹,春花似锦、人声如沸。这庄子的主人今日做“春日...
    开封第一讲书人阅读 29,978评论 0 19
  • 文/苍兰香墨 我抬头看了看天上的太阳。三九已至,却和暖如春,着一层夹袄步出监牢的瞬间,已是汗流浃背。 一阵脚步声响...
    开封第一讲书人阅读 31,206评论 1 260
  • 我被黑心中介骗来泰国打工, 没想到刚下飞机就差点儿被人妖公主榨干…… 1. 我叫王不留,地道东北人。 一个月前我还...
    沈念sama阅读 45,092评论 2 351
  • 正文 我出身青楼,却偏偏与公主长得像,于是被迫代替她去往敌国和亲。 传闻我的和亲对象是个残疾皇子,可洞房花烛夜当晚...
    茶点故事阅读 42,510评论 2 343

推荐阅读更多精彩内容