zoukankan      html  css  js  c++  java
  • java main方法背后的故事?(转)

    jvm java 看似一种语言,实则一个巨大的体系的王国,开发这么多年了,还是没有搞懂,我以为我懂了,可是过了一段时间又忘了,所以说还是没懂

    1、main方法说起

    编译完我们的java文件后,需要有个一含有main方法的类,java 命令将指示操作系统启动一个jvm进程

    这个jvm进程启动后,寻找那个main地方开始执行程序

    java [JVM_Options] ClassName_with_main [args_separate_space]

    main方法的签名必须是 pubic static void main(String[] args) why?

    简单点:

    首先,main方法是JVM(java虚拟机)自动调用

    JVM调用main方法的位置自然不会在某个类中、或某个包中,因此只有当main方法在公有级别上时,才对JVM可见,所以mian方法需要public修饰,

    main方法所在的类也需要public修饰符。

    由于main方法是所有程序的入口,也就是main被调用时没有任何对象创建,不通过对象调用某一方法,只有将该方法定义为静态方法,所以main方法是一个静态方法,既需要static修饰。

    JVM对于java程序已经是最底层,由它调用的方法的返回值已经没有任何地方可去,因此,main方法返回值为空,既需用void修饰。

    至于main方法的参数String[ ] arg我们现在已经很少有机会去用它了,它用于在接受命令行传入的参数

     2、执行main方法之前发生了神马

    可以参看 jvm源码分析     

    首先要明确 jvm进程 是操作系统的进程,该进程是多线程机制的

    我们明确两种线程:

    jvm线程:指jvm自行管理的线程,我们在程序中无法操控,多是守护类型的

    java线程:指从java技术角度看 jvm、我们在程序中用Thread类或Runnable接口编写产生的线程,可操控的线程

    至于 java线程 在 jvm里面是怎么实现的,怎么对应到os级别的线程的,请看  http://my.oschina.net/jingxing05/blog/275334

    明确两类不同的线程之后,执行main方法之前: LoadJavaVM

    jvm进程启动了多个jvm线程(很可能是错的,如有,请赐教):

    jvm线程:

    • 启动 VM Thread, 单例的,所有线程之始祖!这个线程自轮询loop从对一个队列中取操作任务,来产生其他线程

    • 根据jvm抽象规范,可能有执行引擎线程GC线程classloader线程

    在jvm自身启动和初始化之后,会

    ContinueInNewThread(JavaMain, threadStackSize, (void*)&args);

    即启动一个叫main的线程来执行  入口的main方法,main线程虽然不是我们手动生出的线程,但ta还是一个非守护线程

    3、main执行过程

    • 加载类

    执行main方法时,jvm进程发现main所在类没有在方法区,于是开始进行classload

    类加载完的最后一步是 根据情况决定  是不是要进行类的初始化

    在main执行之前,必须先对类进行初始化。初始化类的变量,还有静态代码块。初始化的时候还要先初始化它的父类。每个类都有一个隐含的父类Object。 

    初始化的顺序:类变量和静态块按序,先父后子

    类的初始化过程发生时刻: 

    1. T是一个类,当T的一个实例创建的时候,也就是T t = new T(); 

    2. T的一个静态方法被调用的时候,也就是 T.staticField(); 

    3. T的静态属性被赋值的时候,T.staticField = o; 

    4. T的一个静态属性被使用的时候,也就是 Object o = T.staticField; 但是它不是常量。 

    5. T is a top level class , and an assert statement  lexically nested 

    within T  is executed. (不懂,求解) 

    • 执行main方法

    将方法需要的参数,局部变量,本地方法,操作数等以 栈帧的结构 push到 main线程的堆栈区,然后执行引擎线程开始执行,执行完毕,将该栈帧 pop掉。main线程的堆栈区没有栈帧时,main线程消退。

    • 卸载类对象

    这一步是个优化的步骤,释放一些方法区的内存,jvm自己决定要不要这一步,一般不会去卸载方法区的

    • 程序退出

    1. 所有的非daemon线程都终止了 

    2. 某个线程调用了类Runtime或者System的exit方法

    main程序执行图

     

    类加载详细过程

    jvm中的一些线程可参看 http://ifeve.com/jvm-thread/

    http://my.oschina.net/jingxing05/blog/282867?p={{currentPage+1}}

  • 相关阅读:
    POJ:1703-Find them, Catch them(并查集好题)(种类并查集)
    POJ:2236-Wireless Network
    POJ:2010-Moo University
    POJ :3614-Sunscreen
    POJ:2395-Out of Hay
    Aizu:2224-Save your cats
    POJ:2377-Bad Cowtractors
    CSS属性大全
    博客园背景设置CSS代码
    W3C标准以及规范
  • 原文地址:https://www.cnblogs.com/softidea/p/5175069.html
Copyright © 2011-2022 走看看