讨论,把JAVA编译成不依赖于JVM的EXE文件的可行性

小灰狼 2011-09-05 10:46:43
不断有人提出想把java源程序编译成exe,除了一些认为软件就是exe的初学者之外,多少在这方面应该还有一定的市场需求吧。但是目前业界还是没有出现能够把java源程序编译成不依赖于jvm的编译器出现,会不会是技术上有问题呢?

我想到的是,问题应该出现在JAVA的内存回收机制上。我们知道,在JAVA中没有象C++那样的delete操作,当JAVA创建了对象之后,什么时候回收对象所占用的内存是由JVM完成的。如果编译成exe,那么必然在编译好的exe中加入一套内存回收机制,否则随着程序的运行,对内存只吃不吐,不多久就会把系统内存吃光。但是windows的exe程序里似乎要达到这个目的并不好办,因为在微软的dot net 应用程序也虽然也使用了类似java那样的自动内回收机制,但dot net的exe也是在一个虚拟环境下运行的,并不是纯exe代码。

欢迎讨论!
...全文
651 28 打赏 收藏 转发到动态 举报
写回复
用AI写文章
28 条回复
切换为时间正序
请发表友善的回复…
发表回复
吴锦波 2011-09-08
  • 打赏
  • 举报
回复
用exe4j这个工具吧
先把项目打包成jar,然后再用exe4j这个工具转成exe文件就可以了
网上有很多关于这个工具的使用说明,楼主可以到网上搜索一下的
小灰狼 2011-09-08
  • 打赏
  • 举报
回复
[Quote=引用 27 楼 jinbogameboy 的回复:]

用exe4j这个工具吧
先把项目打包成jar,然后再用exe4j这个工具转成exe文件就可以了
网上有很多关于这个工具的使用说明,楼主可以到网上搜索一下的
[/Quote]

我想你误会了
我想讨论的是java到不依赖虚拟机的exe的可能性,而不是我有这方面的需求。事实上,我认为这是不可行的。你说的exe4j其实不过是把虚拟机放到exe里罢了。
小灰狼 2011-09-07
  • 打赏
  • 举报
回复
23楼的朋友

Borland的vcl和Qt的QObject都是例子,通过对象的父子/从属关系来销毁实例
Java当初没有选择这么做,是因为他已经有了jvm这是个更全面的解决办法,
正也是因为这个解决办法,它不需要显性释放内存的语句,所以在语法中没有设计相关语法
而不是倒过来理解,因为他没有这种语句,所以他需要依赖jvm
"需要依赖jvm"是结果而不是原因
------------------------------------------------
呵呵,这个看起来象个哲学问题了。
我倒是觉得,现在java没有释放内存的语句这个即成事实,导致了它无法编译成exe的结果。当然要从哪个方面看了。

VCL我不懂,但从你说的它是依靠父子/从属关系来确定对象的销毁这个原理来看,这似乎应该和VCL的类的设计有关,这个应该无法适用到java上。因为java里随时都可以用 new 去创建一个对象,这个对象不可能存在于系统的栈空间,而只能在堆空间,很多对象之间并不存在很强的父子/从属关系。或者说,VCL在设计时就是考虑用它的对象销毁机制,而java则是自动内存回收机制,两者不可以套用的,就象潜艇在水下走,飞机在天上飞,它们之间运动、停靠的原理都不一样,不能套用一样。



有所得必有所失,相信java从来没有考虑过要编译成纯win32/64现在硬要他做他本来就不想做的事情,有点和潘长江比身高,和姚明比灵活的意味
而且如果要从对vm的依赖性来看的话那岂不是.net从开始就已经失败了
----------------------------------------------
我只是想讨论一下java编译成exe的可行性,特别是 java to exe 的过程中 GC 问题如何解决的问题,因为论坛里经常有人问如何将 java 做成 exe,所以不免在这方面有了一些思考而已。其实我从来没有认为软件就一定是 exe,也不能认为依赖于VM的软件就不叫软件。
idilent 2011-09-07
  • 打赏
  • 举报
回复
我觉得还是讨论一下,怎么让软件脱离计算机比较有理想!
yktd26 2011-09-07
  • 打赏
  • 举报
回复
[Quote=引用 24 楼 hemowolf 的回复:]
呵呵,这个看起来象个哲学问题了。
我倒是觉得,现在java没有释放内存的语句这个即成事实,导致了它无法编译成exe的结果。当然要从哪个方面看了。

VCL我不懂,但从你说的它是依靠父子/从属关系来确定对象的销毁这个原理来看,这似乎应该和VCL的类的设计有关,这个应该无法适用到java上。因为java里随时都可以用 new 去创建一个对象,这个对象不可能存在于系统的栈空间,而只能在堆空间,很多对象之间并不存在很强的父子/从属关系。或者说,VCL在设计时就是考虑用它的对象销毁机制,而java则是自动内存回收机制,两者不可以套用的,就象潜艇在水下走,飞机在天上飞,它们之间运动、停靠的原理都不一样,不能套用一样。
[/Quote]

我只是想讨论一下java编译成exe的可行性,特别是 java to exe 的过程中 GC 问题如何解决的问题,因为论坛里经常有人问如何将 java 做成 exe,所以不免在这方面有了一些思考而已。其实我从来没有认为软件就一定是 exe,也不能认为依赖于VM的软件就不叫软件。
[Quote=引用 24 楼 hemowolf 的回复:]
这个问题,世界上没有自动的东西,各种对象的实例也都在堆里,gc无非是查找已经没有引用的实例
只是何时查找,如何查找的问题
发展到现在java肯定不会去套用其他的机制,我想说的是当初他没有选择去套用,因为他已经有了jvm
[/Quote]
如果楼主真的想研究java编译成纯 win32 app,gc可能不是第一个要考虑的切入点,应该也不是最困难最繁琐的一步,个人觉得可能要研究的是jvm在字节码和win之间所做的工作,而将这些工作由编译器完成,不过这个工作可能确实是一般人完成不了的
之前看到过有人也做过c/c++的garbage collector,如果想研究这个方向也算是一个参考,总而言之,个人并不觉得gc是vm存在的价值,只是多数vm的一个属性


zhanghua4109 2011-09-06
  • 打赏
  • 举报
回复
把java文件编译成jar,用bat,或exe可以执行。
旭子 2011-09-06
  • 打赏
  • 举报
回复
楼主 如果硬想这么做的话就包装一个exe来把java代码当作jar包来调就是了,也就是用C来调JAVA
旭子 2011-09-06
  • 打赏
  • 举报
回复
楼主 如果硬想这么做的话就包装一个exe来把java代码当作jar包来调就是了,也就是用C来调JAVA
旭子 2011-09-06
  • 打赏
  • 举报
回复
楼主 如果硬想这么做的话就包装一个exe来把java代码当作jar包来调就是了,也就是用C来调JAVA
qybao 2011-09-06
  • 打赏
  • 举报
回复
在微软官方网找到的一个信息 http://support.microsoft.com/kb/299764/EN-US

里面有段话
When you install Visual J++ on a computer running a fresh installation of Windows Server 2003 or Windows XP, or when you upgrade to Windows XP on a computer that is running Windows 95, Windows 98, Windows NT, or Windows 2000, you may have to update the Microsoft virtual machine (Microsoft VM) to version 5.00.3200 or later. When you start to install the program, you may experience one of the following problems:

On a new install of Windows Server 2003 or Windows XP
You may receive the following error message:
Microsoft Visual J++ has a known compatibility issue described in Microsoft Knowledge Base article Q299764. Microsoft Visual J++ customers must correct this issue before using Visual J++.

Windows blocks the Visual J++ install program until you install or update the Microsoft VM.
从红色部分可以知道,windows曾经是自带Microsoft VM,win2k以后,不一定所有本版都可能自带该组件
从蓝色部分可以知道,VJ是需要VM的
qybao 2011-09-06
  • 打赏
  • 举报
回复
[Quote=引用 15 楼 hemowolf 的回复:]
如果说VJ只是一个外壳的话,那么要运行VJ写的 windows 应用程序也应该需要安装一下环境才可以运行。

但是,2000年的时候,我就在一个ASP的系统上用到过几个当时公司里其他同事用VJ写的ocx控件,文件不大,一般都不到1M,用 Regsvr32.exe 注册就可以使用。后来我们把系统部署到 windows 2000 上,也可以正常使用,那台 windows 2000 应该没有安装什么开发工具或者VJ的环境。

不过可能时间太久了,当时偶还刚出道,没什么经验,一些细节可能忘记了。我找个JV试一下看。
[/Quote]
当时的Windows应该是自带VM的,因为IE也需要
小灰狼 2011-09-06
  • 打赏
  • 举报
回复
[Quote=引用 14 楼 qybao 的回复:]
VJ发布的exe应该只是一个外壳,也需要运行于Windows系统自带的Microsoft VM上,LZ如果有兴趣,可以去找找以前的VJ教材看看,也可以在网上搜索一下 微软Visual J++常见问题解答 的相关网站看看。
其实想想也可以知道,没有一个智能的编译器能够给开发的程序自动编译加上垃圾回收的功能,因为程序的开发千变万化,垃圾回收的功能不应该交给编译器,因为编译器不可能预测每个开发者开发的程序。如果编译器想做,就只能外部做好一个通用的垃圾回收dll,然后编译时自动把该dll编连,这就和上面说的把jre打包到exe是一个相同的道理。如果不想把dll编连或jre打包,那么垃圾回收就需要交给开发者来完成。退一步来说,我们假设垃圾回收功能每个开发者都可以用开发语言自己实现,那么是开发一个垃圾回收器容易呢还是开发者自己申请内存自己清空内存容易呢?所以很显然,如果要想java->exe,那么垃圾回收功能不是交给java编译器,也没必要交给开发者去完成(因为开发一个程序好需要额外的开发,显然没必要),所以最好的做法就是开发者自己申请内存自己清除,也就是说,java语言需要改版,提供垃圾回收的方法,这样又回到了C/C++的道路上了。
[/Quote]

如果说VJ只是一个外壳的话,那么要运行VJ写的 windows 应用程序也应该需要安装一下环境才可以运行。

但是,2000年的时候,我就在一个ASP的系统上用到过几个当时公司里其他同事用VJ写的ocx控件,文件不大,一般都不到1M,用 Regsvr32.exe 注册就可以使用。后来我们把系统部署到 windows 2000 上,也可以正常使用,那台 windows 2000 应该没有安装什么开发工具或者VJ的环境。

不过可能时间太久了,当时偶还刚出道,没什么经验,一些细节可能忘记了。我找个JV试一下看。
qybao 2011-09-06
  • 打赏
  • 举报
回复
[Quote=引用 13 楼 hemowolf 的回复:]
我们说 java 能自动进行内存管理,是因为它运行在 JVM 上,而JVM实现了自动内存管理
而 exe 运行在 windows 操作系统上,但 windows 没有提供这个功能,而 java 语言也没有提供类似 C/C++ 那样的 free 或 delete 操作,所以用java编译成的exe就无法进行内存的释放工作了。只申请内存,而不释放内存的应用程序肯定是不能用的。所以,java to exe 这类编译器必须要使目标代码有自动释放内存的功能。

在1999年时,MS随着 visual studio 6.0 一起发布了 Visual J++,它可以把jdk1.1版本的java程序编译成exe,或者dll和ocx,并且可以在没有安装jdk的windows上运行,并且文件也不大。那时还没出道,没想那么多,现在回想起来有点纳闷,他们怎么解决内存回收回题的。
[/Quote]
VJ发布的exe应该只是一个外壳,也需要运行于Windows系统自带的Microsoft VM上,LZ如果有兴趣,可以去找找以前的VJ教材看看,也可以在网上搜索一下 微软Visual J++常见问题解答 的相关网站看看。
其实想想也可以知道,没有一个智能的编译器能够给开发的程序自动编译加上垃圾回收的功能,因为程序的开发千变万化,垃圾回收的功能不应该交给编译器,因为编译器不可能预测每个开发者开发的程序。如果编译器想做,就只能外部做好一个通用的垃圾回收dll,然后编译时自动把该dll编连,这就和上面说的把jre打包到exe是一个相同的道理。如果不想把dll编连或jre打包,那么垃圾回收就需要交给开发者来完成。退一步来说,我们假设垃圾回收功能每个开发者都可以用开发语言自己实现,那么是开发一个垃圾回收器容易呢还是开发者自己申请内存自己清空内存容易呢?所以很显然,如果要想java->exe,那么垃圾回收功能不是交给java编译器,也没必要交给开发者去完成(因为开发一个程序好需要额外的开发,显然没必要),所以最好的做法就是开发者自己申请内存自己清除,也就是说,java语言需要改版,提供垃圾回收的方法,这样又回到了C/C++的道路上了。

小灰狼 2011-09-06
  • 打赏
  • 举报
回复
[Quote=引用 11 楼 yktd26 的回复:]

看不到垃圾回收机制和java程序需要依赖jvm之间有任何关系

个人觉得这个问题就好象为什么.doc文件需要word打开,
如果微软想,他尽可以直接用windows直接打开.doc
我们为什么需要word这一层,
因为微软想这么做
java的缔造者没有能力把.java编译成.o进而连接成.exe?我不这么觉得
.class和jvm的存在,应该只是要实现他们的概念

Qt(C++……
[/Quote]

首先,一个应用程序运行时一定会申请内存,并且内存申请用完之后一定要释放,这一点您应该不会反对吧

接下来,就是如何释放内存的问题了。在C/C++里,如果你用 new 操作创建了一个对象,那么应该在这个对象不需要再使用的时候用 delete 操作销毁它,否则这个对象会一直占用它的内存,随着程序不断运行,内存吃吃不吐,总会有消耗殆尽的时候。而在java程序里,由于java运行在JVM上,而JVM跟踪了内存对象及其引用的状态,所以在java程序里不需要进行delete操作,JVM会自动根据它对内存对象的状态跟踪情况完成内存的释放工作。

简而言之,就是C/C++程序运行在操作系统环境上,由程序控制内存的释放工作,操作系统不会自动帮应用程序释放内存;JAVA程序运行在JVM环境上,由JVM环境完成内存释放工作,JVM可以帮应用程序释放内存。

最后得到这样一个疑问:操作系统没有自动内存管理,JAVA源程序里也没有释放内存的语句,那么编译成exe之后的应用程序如何释放内存?
小灰狼 2011-09-06
  • 打赏
  • 举报
回复
[Quote=引用 10 楼 qybao 的回复:]
LZ好像有点小小的概念误区,你这里所说的垃圾回收机能,不应该有程序本身提供,也就是说程序运行在什么之上,就由底层的什么系统来提供,就好像java程序运行于JVM,垃圾回收由JVM提供,并不是java程序自己提供。所以你这里所谓的垃圾回收机能,只能由操作系统来提供,程序能做到的只能是自己申请自己回收,否则就只能像上面说的,自己exe中开启一个后台进程管理自己的进程空间(不是管理整个操作系统的内存空间),因为exe是运行于操作系统之上,操作系统不知道也不需要知道exe由什么语言编写而成,所以你这里所说的垃圾回收问题,不是java本身的问题,而是所有开发语言的共同问题。所以这样的垃圾回收和你所谓的编译成exe并不是一个问题。
[/Quote]

我们说 java 能自动进行内存管理,是因为它运行在 JVM 上,而JVM实现了自动内存管理
而 exe 运行在 windows 操作系统上,但 windows 没有提供这个功能,而 java 语言也没有提供类似 C/C++ 那样的 free 或 delete 操作,所以用java编译成的exe就无法进行内存的释放工作了。只申请内存,而不释放内存的应用程序肯定是不能用的。所以,java to exe 这类编译器必须要使目标代码有自动释放内存的功能。

在1999年时,MS随着 visual studio 6.0 一起发布了 Visual J++,它可以把jdk1.1版本的java程序编译成exe,或者dll和ocx,并且可以在没有安装jdk的windows上运行,并且文件也不大。那时还没出道,没想那么多,现在回想起来有点纳闷,他们怎么解决内存回收回题的。

yktd26 2011-09-06
  • 打赏
  • 举报
回复
[Quote=引用 13 楼 hemowolf 的回复:]

引用 11 楼 yktd26 的回复:

看不到垃圾回收机制和java程序需要依赖jvm之间有任何关系

个人觉得这个问题就好象为什么.doc文件需要word打开,
如果微软想,他尽可以直接用windows直接打开.doc
我们为什么需要word这一层,
因为微软想这么做
java的缔造者没有能力把.java编译成.o进而连接成.exe?我不这么觉得
.class和jvm的存在……
[/Quote]

这是不是一个逻辑问题?
楼主认为java离不开jvm是因为无法实现gc
但我更觉得java 的整个设计是先因为要跨平台所以要jvm然后因为有了jvm所以选择了gc的处理放在jvm上
真的没有其他办法处理gc么?
Borland的vcl和Qt的QObject都是例子,通过对象的父子/从属关系来销毁实例
Java当初没有选择这么做,是因为他已经有了jvm这是个更全面的解决办法,
正也是因为这个解决办法,它不需要显性释放内存的语句,所以在语法中没有设计相关语法
而不是倒过来理解,因为他没有这种语句,所以他需要依赖jvm
"需要依赖jvm"是结果而不是原因
有所得必有所失,相信java从来没有考虑过要编译成纯win32/64现在硬要他做他本来就不想做的事情,有点和潘长江比身高,和姚明比灵活的意味
而且如果要从对vm的依赖性来看的话那岂不是.net从开始就已经失败了
小灰狼 2011-09-06
  • 打赏
  • 举报
回复
[Quote=引用 17 楼 qybao 的回复:]

在微软官方网找到的一个信息 http://support.microsoft.com/kb/299764/EN-US

里面有段话
When you install Visual J++ on a computer running a fresh installation of Windows Server 2003 or Windows XP, or when you upgrade t……
[/Quote]

嘿嘿,这正好证明了我的观点:因为JAVA没有回收内存的语句,因此想把它编译成与操作系统直接打交道的可执行代码的可行性不高。因为连当初MS自己开发的编译器编译出来的exe都要运行在VM上。

如果哪家公司想开发一个编译器,将java编译成只在特定操作系统上运行的可执行代码或库,那么他必须要开发一个VM,至少在内存释放是必须要有的。而如果一个exe还要运行在VM上,那还不如直接用JVM。
qybao 2011-09-05
  • 打赏
  • 举报
回复
[Quote=引用 4 楼 gsy999 的回复:]
引用楼主 hemowolf 的回复:
不断有人提出想把java源程序编译成exe,除了一些认为软件就是exe的初学者之外,多少在这方面应该还有一定的市场需求吧。但是目前业界还是没有出现能够把java源程序编译成不依赖于jvm的编译器出现,会不会是技术上有问题呢?

我想到的是,问题应该出现在JAVA的内存回收机制上。我们知道,在JAVA中没有象C++那样的delete操作,当JAVA创建了对……
[/Quote]
我的意思就是说没有必要,不是技术做不到,依赖dll和依赖jre是一样的,在C/C++中利用JNI调用jvm.dll开发做成exe的也有不少,JVM的版本也不少,开发商能开发JVM解析伪代码,难道还不能把解析后的目标指令代码做成exe? 垃圾回收不过也就是一个线程而已,在exe进程中启动一个线程不也是很简单吗?所以也没什么可行性分析的,只是有没有必要而已。

gsy999 2011-09-05
  • 打赏
  • 举报
回复
[Quote=引用楼主 hemowolf 的回复:]
不断有人提出想把java源程序编译成exe,除了一些认为软件就是exe的初学者之外,多少在这方面应该还有一定的市场需求吧。但是目前业界还是没有出现能够把java源程序编译成不依赖于jvm的编译器出现,会不会是技术上有问题呢?

我想到的是,问题应该出现在JAVA的内存回收机制上。我们知道,在JAVA中没有象C++那样的delete操作,当JAVA创建了对象之后,什么时候回收对象所占用的内存是由……
[/Quote]
java的初衷是跨平台,一次编写处处运行,可是整成真正意义的与操作系统API打交道的exe,那还能跨平台吗?历史上是有能把java整成exe文件的软件的,但是那只是加个壳,实际运行时,还是要运行在jvm之上。至于做在exe需要解决的回收问题,请看看D语言吧:
  “在 D 中,所有的类都通过引用来访问。这样就不需要复制构造函数、赋值运算符、复杂的析构语义以及同异常处理中的堆栈展开的相互作用。内存资源由垃圾收集程序负责释放,其他资源通过使用 D 的 RAII 特征释放。”
  因此我的看法是,问题的核心不在于java-->exe的过程有多么难,而是有没有必要。






qybao 2011-09-05
  • 打赏
  • 举报
回复
LZ想的比较单纯,并不只是为了垃圾回收。
JVM只是相当于一个解析器,把java的伪代码指令翻译成真正的机器指令(二进制代码)去执行
如果编译成exe,就要把java的伪代码编译成目标机器指令,这样java就不能达到跨平台,因为只能针对某个目标机器去编译了,这样违背了当时java的初衷。同时,因为java本身提供了JVM解析器,编译成exe时,直把JVM解析器打包到exe,让JVM去解析就可以了,没必要再自己开发出一个解析器出来。不过,如果把JVM打包到exe,就会导致exe很大(因为JVM还需要很多核心的类,即jre环境,把这些类都打包到exe那文件要多大啊,除非把这些类都改写成dll或lib什么的),所以把JVM当作外部资源来使用就好了。这样,就相当于exe还是依赖于外部的JVM。同样的,这里可以知道,其实exe又是也会依赖于某些dll或lib,如果系统缺少这些dll或lib也一样不能执行,所以从这个角度上来说,exe依赖dll或lib和依赖jre环境是相饰的,所以就没必要非要让exe独立于jre环境了。

加载更多回复(8)

62,614

社区成员

发帖
与我相关
我的任务
社区描述
Java 2 Standard Edition
社区管理员
  • Java SE
加入社区
  • 近7日
  • 近30日
  • 至今
社区公告
暂无公告

试试用AI创作助手写篇文章吧