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}}
java main方法背后的故事?(转)的更多相关文章
- 07 java main方法
1.问题:Java main方法为什么是 public static void main(String[] args)??? 序号 场景 编译 运行 解释 1 public修改为private pr ...
- 从java main方法说开去(转)
刚刚接触java语言时,接触的便为一个java main方法.我们知道这样程序就可以运行了,但是程序是怎么运行起来的我们却不知道. 众所周知,当执行一个java程序时,首先会启动一个JVM虚拟机进程, ...
- java main方法
1.问题:Java main方法为什么是 public static void main(String[] args)??? 序号 场景 编译 运行 解释 1 public修改为private pr ...
- 为什么使用Junit Test而不用普通java main方法来完成测试?
因为在程序里边,一个接口对应一个实现方法,而在接口中常常会定义相关的很多方法,所以在测试的时候,如果都在main方法里边进行测试,main方法就会显得臃肿,而且不便于以后其他人测试以及查看测试数据,用 ...
- public static void main(String[] args){} 关于Java main()方法
是Java程序的入口方法,JVM在运行程序时,会首先查找main()方法. public是权限修饰符,表明任何类或对象都可以访问这个方法: static表明main()方法是一个静态方法,即方法中的代 ...
- Java main方法继承
java中main方法是可以继承的 Test1.java package Variables; public class Test1 { public static void main(String[ ...
- linux shell脚本调用java main方法 代码传值
#!/bin/bash #description: ljdjService export PRG_HOME=/ainmc/work/toptea/dataTransfer PRG_KEYWORD=pr ...
- linux shell脚本调用java main方法 代码
#!/bin/sh # #该脚本为Linux下启动java程序的通用脚本.即可以作为开机自启动service脚本被调用, #也可以作为启动java程序的独立脚本来使用. # #Author: tuda ...
- Java基础学习总结(78)——Java main方法深入研究学习
1.不用main方法如何定义一个类? 不行,没有main方法我们不能运行Java类. 在Java 7之前,你可以通过使用静态初始化运行Java类.但是,从Java 7开始就行不通了. 2.main() ...
随机推荐
- ubuntu下使用自带的openJDK查看java源码
如题 Ubuntu自带的OpenJDK仅仅有jre环境,不提供源代码,所以我们还是须要去下载. JDK6:http://download.java.net/openjdk/jdk6/ JDK7:htt ...
- AlarmManager的学习与实现
综述 这个类提供了一种使用系统提供的alarm服务.这个服务同意用户安排他们的应用程序在将来的某一个时间点执行.当设置的alarm响起,那么之前系统为这个alarm注冊的Intent就会自己主 ...
- linux下使用vi操作
ESC : 进入命令模式 linux下使用vi后,怎样跳转到文件结尾 pagedown键连续按 虽然我也这么用,但还是太笨了.问了高手,方法是按shift+g,另外,到文件开头是gg. linux ...
- webservice一片:其中在外线呼叫数据,查看返回数据
经Android数据被访问,返回的数据(json格公式,object数据类型:strJson) 业务需求:经webservice调用外部暴露数据并返回json数据序列化.阅读到数据库表:[SQ_Eve ...
- WCF配置文件
因为要上传较大的图片,WCF传递数组的默认的最大数组16KB就不够了.以下讲解配置内容. 服务端配置 这里一个WCF项目中有1个服务,配置文件如下(位于system.serviceModel标签中): ...
- MySQL 批量Dll操作(转)
概述 本章节介绍使用游标来批量进行表操作,包括批量添加索引.批量添加字段等.如果对存储过程.变量定义.预处理还不是很熟悉先阅读我前面写过的关于这三个概念的文章,只有先了解了这三个概念才能更好的理解这篇 ...
- hdu1372 dfs搜索之国际象棋的马
原题地址 题意 一个8x8的国际象棋棋盘,你有一个棋子"马".算出棋子"马"从某一格到还有一格子的最少步数. 与普通dfs不同的是,你能走的路线不是上下左右,四 ...
- AndroidService 深度分析(2)
AndroidService 深度分析(2) 上一篇文章我们Service的生命周期进行了測试及总结. 这篇文章我们介绍下绑定执行的Service的实现. 绑定执行的Service可能是仅为本应用提供 ...
- spring改版官网下载jar包, 源代码和文档
从网上找了一些方法,现在都整理了一下,有简单粗暴的,也有百转回肠的(详细,直接从官网一步一步的进入下载页),希望大家根据自己的喜好可以找到的真爱. 方法一:(简单粗暴直接) http://repo.s ...
- 删CentOS / RHEL库和配置文件(Repositories and configuraiton files)
1 删除库简介 随着root权限执行以下的命令: # cd /etc/yum.repos.d/ 列出全部库(repo) #ls CentOS-Base.repo epel.repo mirrors-r ...