java-程序执行原理
java应用可以打包成jar 格式,jar格式其实只是一种很普通的压缩格式,与zip格式一样,只不过是它会在压缩文件的目录结构中增加一个META-INF/ MANIFEST.MF 的元文件。
我们知道,经过编译的字节码class文件可以直接放到java虚拟机去解释执行(JIT方式), 我们通过在命令行调用“java class文件的路径”就可以使用jvm(java.exe/javaw.exe)来解释执行这些字节码文件。
我们知道,java源代码(.java文件)经过java编译器javac编译以后,会得到java的字节码的中间语言文件,也就是我们通常所说的类文件(.class文件),这些类文件会按照java源文件的包结构分目录存放,jar 命令的作用就是按照这种包目录结构打包这些字节码的class文件,形成一个jar包,并且增加一个META-INF/ MANIFEST.MF 的元文件 。这样打包的jar文件的确是包含了按照包目录结构存放的字节码class文件,但是这时候如果你在命令行:jar -jar a.jar 的话,会提示你指定一个主类,这是因为,虽然jar包里面包含了按照包目录结构存放的字节码class文件,但是却并不知道主类(含有 public static void main(String[])入口 方法的类)的位置,所以需要你手动的指定主类,然后才可以开始执行。
当然,只需要在打包jar文件的时候,将主类的信息包含进去了以后,再:jar -jar a.jar 的话, 就不需要手动的指出主类是哪个类了。进行如下操作:
新建一个.mf文件,名字任意,例如:manifest.mf ,在里面指定主类是哪个类,即:写入一行 :Main-Class: test.Test。然后,打包: jar cvfm test.jar manifest.mf test; 这样打成的包test.jar里面就已经包含主类是哪个类的信息了。这样的话,在命令行里面直接执行:jar -jar test.jar 就可以运行该应用了,这种情况下, jvm会去这个class文件的包中寻找入口函数如何进入执行。
我们发布java应用的时候,直接发布按照包结构存放的class文件夹显然是很不方便的,一般需要打包成jar文件来发布。 就好象我们将java应用部署到tomcat web 服务器上去的时候一样, 虽然直接将按照包结构存放的class文件夹放过去是可以的,但是通常还是要打包成jar包的格式来部署,因为这样文件的数量会少,便于管理部署的。
将命令行的“java -jar jar 文件的路径” 写到一个.bat文件里面 或者linux下面的shell文件里面,这样就可以通过执行.bat文件或者shell脚步来执行java 应用程序了,也就是说可以直接双击windows下的.bat文件或者linux下的.sh文件来运行java应用程序了。
一般在安装jre (Java Runtime Environment) 的时候,安装文件会将 .jar 文件映射给 javaw.exe 打开,如果没有关联,也可以手动的通过文件夹选项来手动关联,关联以后,当用户在windows下双击jar文件的时候,资源管理器就会调用javaw来运行该jar文件,这样就可以实现双击运行jar文件了。
jdk 相关过程原理分析。
我们知道,在jdk的bin目录下有很多的exe文件,例如java.exe, javac.exe, javadoc.exe等。 这些exe文件格式实质上是windows操作系统下的可执行文件格式(在dos下还有一种可执行可是是.com后缀的格式,不过现在已经不常见了),它们是由C语言写成的.c文件经过编译后生成的。
例如:java.exe对应的源码就是java.c文件。java.c的main入口函数中会调用函数:CreateExecutionEnvironment,该函数中会查找jre路径,然后根据jvm.cfg配置文件配置的虚拟机动态链接库(jvm.dll)路径参数装载jvm.dll动态连接库,也就是加载java虚拟机(java虚拟机是C++写的,也有部分C代码),然后初始化jvm.dll(所有的dll都是本地语言写成的), 并挂接到JNIEnv(JNI调用接口)实例,最后调用JNIEnv实例装载并处理class类。
由上面的分析我们可以看到,windows操作系统下的exe文件大部分情况下是使用windows本地语言所写的代码编译而成的的,这些exe文件用于完成一定的功能,例如java.exe, 可以用来查找并加载jvm.dll ,然后通过调用jvm.dll 的 接口来加载java的字节码中间语言文件.class文件,并启动java应用程序。 或者完成其它的一些功能等。exe文件也可能是本地语言代码生成的exe文件与jar包压缩而成的。
更加方便的方法是,将jar做成exe。例如eclipse 就是一个java 应用程序,就采用了使用exe来wrapper。
wrapper 基本原理: 在本地化语言(C或者C++等)代码中调用jvm.dll,然后通过jvm.dll提供的接口加载压缩在一起的jar包中的主类class的入口方法( static void main(String args[]), 从而启动java应用程序,这种加壳方式形成的java应用的exe文件在启动的时候会表现为一个exe进程,这种方式更常见。(形式是一个由本地化语言exe和jar包一起压缩而成的一个exe文件);
也可以在本地化语言(C或者C++等)代码中调用java.exe/javaw.exe进程(java.exe进程会执行前一种方法的步骤来完成jvm.dll的加载)来加载jvm.dll,然后通过jvm.dll提供的接口加载压缩在一起的jar包中的主类class的入口方法( static void main(String args[]), 从而启动java应用程序,这种加壳方式形成的java应用的exe文件在启动的时候会表现为一个exe进程和一个javaw进程。(形式是一个由本地化语言exe和jar包一起压缩而成的一个exe文件,当然,也可以选择不将jar文件和本地exe文件压缩在一起);
这两种根本上都是通过本地代码来加载java虚拟机,然后在本地代码中通过调用jvm.dll的接口来完成class主文件的加载和java应用的启动的。
具体来说,也有很多种方法。
可以使用c语言等本地语言创建一个本地代码(编译后生成exe文件),在该本地代码中加载jvm的动态库,并通过动态库的接口来在本进程内启动java虚拟机,即调用JNI_CreateJavaVM这个导出函数来创建Java虚拟机,得到JNIEnv指针,然后调用FindClass查找Main Class,之后调用GetStaticMethodID方法得到main方法,并执行main方法。 编译该本地代码得到一个exe文件。
将Java应用程序的class目录结构打包为jar文件,并与本地代码exe文件合并:在Dos提示符下执行copy命令:
C:/>copy test.exe+test.jar test.exe
其实,就是将Java打包文件追加到exe文件尾部。打开文件属性对话框,可看到有“压缩文件”属性页。
老牌的JBuilder.exe开发工具编译生成的exe文件即采用如下方式生成。
这很简单,启动vc,建一个win32 project,WinMain里使用ShellExecute函数即可,主要代码是:
#include "stdafx.h"
#include "resource.h" int APIENTRY WinMain(HINSTANCE hInstance,
HINSTANCE hPrevInstance,
LPSTR lpCmdLine,
int nCmdShow)
{
ShellExecute(NULL,"open",".//jre6//bin//javaw.exe","-ea -Dfile.encoding=GB18030 -Xmx600M -splash:res//splash.png -classpath /"./lib/*/"com.zms.laser.uis.Starter",".//",SW_SHOWNORMAL);
return 0;
}
要给编译出来的可执行程序一个图标,很简单,只要添加一个icon的资源,让这个icon的id最小即可。编译器会把具有最小id的icon当作最终exe的图标。
所有的给java 应用 加 exe 外壳的工具软件采用的都是以上原理中的一种
java-程序执行原理的更多相关文章
- Java基础知识强化之网络编程笔记25:Android网络通信之 Future接口介绍(Java程序执行超时)
1. Future接口简介 在Java中,如果需要设定代码执行的最长时间,即超时,可以用Java线程池ExecutorService类配合Future接口来实现. Future接口是Java标准API ...
- Java基础知识强化之多线程笔记05:Java程序运行原理 和 JVM的启动是多线程的吗
1. Java程序运行原理: Java 命令会启动Java 虚拟机,启动 JVM,等于启动了一个应用程序,也就是启动了一个进程.该进程会自动启动一个 “主线程” ,然后主线程去调用某个类的 m ...
- 性能监控之Java程序执行解析
大家好,最近接触javassist技术,研究过程中对Java程序执行过程进行了一系列探索,弄清楚了几个盲区(仅针对个人而言),现将经验与大家分享. 1.编码->.java 通常指写代码的过程,最 ...
- python笔记:#006#程序执行原理
程序执行原理(科普) 目标 计算机中的 三大件 程序执行的原理 程序的作用 01. 计算机中的三大件 计算机中包含有较多的硬件,但是一个程序要运行,有 三个 核心的硬件,分别是: CPU 中央处理器, ...
- Java性能监控之Java程序执行解析
大家好,最近接触javassist技术,研究过程中对Java程序执行过程进行了一系列探索,弄清楚了几个盲区(仅针对个人而言),现将经验与大家分享. 1.编码->.java 通常指写代码的过程,最 ...
- Java程序运行原理分析
class文件内容 class文件包含Java程序执行的字节码 数据严格按照格式紧凑排列在class文件的二进制流,中间无分割符 文件开头有一个0xcafebabe(16进制)特殊的标志 JVM运行时 ...
- Java程序执行过程及内存机制
本讲将介绍Java代码是如何一步步运行起来的,其中涉及的编译器,类加载器,字节码校验器,解释器和JIT编译器在整个过程中是发挥着怎样的作用.此外还会介绍Java程序所占用的内存是被如何管理的:堆.栈和 ...
- 深入了解Java程序执行顺序
Java中main方法,静态,非静态的执行顺序详解 Java程序运行时,第一件事情就是试图访问main方法,因为main相等于程序的入口,如果没有main方法,程序将无法启动,main方法更是占一个独 ...
- [转]JAVA程序执行顺序,你了解了吗:JAVA中执行顺序,JAVA中赋值顺序
本文主要介绍以下两块内容的执行顺序,熟悉的大虾可以直接飘过. 一.JAVA中执行顺序 静态块 块 构造器 父类构造器 二.JAVA中赋值顺序 静态块直接赋值 块直接赋值 父类继承的属性已赋值 静态变量 ...
- java程序执行顺序
原来自己一直都没弄明白Java程序的执行顺序问题,今天,自己写了个测试,果然与自己考虑的有差距 测试代码: 一个父类Animal 一个子类Dog 测试类Test 运行结果: 所以执行顺序是: 父类An ...
随机推荐
- iOS中自动释放问题?
--前言:iOS开发中关于对象的释放问题,虽然知道规则,但总不清楚自动释放的对象什么时候彻底消失?它存在的多久?什么情况会消失?都不清楚,每次用自动释放对象,总有点心虚的感觉,以下是一些例子.研究. ...
- core_cm3文件函数一览
core_cm3是ARM公司推出来的统一规定,这是对下游芯片厂商的统一规定,因此可以再Cortex-M3(CM3)之间进行移植.此文件中定义了一些对特殊功能寄存器的C语言形式的操作,本质上是内敛汇编和 ...
- ListView的Item被点击和其中的Button被点击同时生效
Android开发中在ListView中经常有Button或ImageButton等需要被点击的控件,如果不加一些特殊的限制,有可能 ListView的Item的点击事件或Button的点击事件,其中 ...
- java通过jsp的Excel导出
在项目中一般导出报表用poi,可是假设你不想用框架就用简单的jsp也能够实现报表导出.并且实现起来还特别简单. 先看一下效果截图: 点击导出后的效果截图: 详细实现: 第一:在页面的列表页面中就是普通 ...
- Python进阶之路---1.4python数据类型-数字
python入门基础 声明:以后python代码未注明情况下,默认使用python3.x版本 1.python代码基础:print print('hello,python') 1.1pyt ...
- 如何让网页打开就运行JS代码,不用onclick
打开网页直接运行是要调用window.onload( )函数: <html> <head> </head> <body> < ...
- Javascript实现表格行排序
网站开发中凡是用到表格来展示数据的,往往都要根据某个列来对行排序,下面是我从书上看到的一个行排序例子,看过后受益匪浅,故分享出来. 直接献上完整代码: <!doctype html> &l ...
- .net简单页面后台绑定下拉框,按钮,分页 前台aspx页面
一.aspx页面 <%@ Page Language="C#" AutoEventWireup="true" CodeBehind="Updat ...
- 用Java来比较JavaScript的一些特性
由于是从java做到JavaScript,所以对强弱语言类型,还是比较敏感的.JavaScript是弱语言,只严格区分数据和指令.简单描述下自己对两者之间的一些区别吧. 1.JavaScript变量的 ...
- 一个很简单的jQuery插件实例教程(菜鸟级)
很多公司的前端设计开发人员都是女孩子,而这些女孩子很多JavaScript技能都不是很好.而前端开发过程中,JavaScript技能又是必不可少的.所以,如果前端小MM正在为某个JavaScript效 ...