据我所知,有不少人
鄙视java,认为它笨重而缓慢,笨重倒是事实,但慢其实是站不脚的,据专业网站的
测评,Java和C/C++的性能平均差距不到两倍,在某些情况下
甚至比C/C++还快。为什么Java给人的印象很慢?主要是在于java的启动速度特别慢,在我的机器上运行HelloWorld的时间需要平均0.35秒,这只是有短暂延时,但第一次启动可能需要2秒或者更长,这种进步得益于
Class Data Sharing技术。一个python版的hello程序大概需要0.05秒,这可以说是“立即”。一个C程序需要5毫秒,仍然是“立即”,对人来说,python和c一样快,java就明显要慢多了。运行一个helloworld的scala脚本就更慢了,最快也要2.5秒,第一次启动时要7秒。总的来说,Java的慢主要体现在启动上,对于一个HelloWorld程序,98%以上的时间花在启动上,真正执行时间只需要4毫秒。
要提高Java的启动速度,一种方法就是让jvm常驻内存,这样就不用每次启动时都去加载一次jvm了,我不知道该怎么做,但肯定不简单,不然的话sun(现在是oracle)早就这么做了。印象中.net的启动速度似乎要比java快,不知是否采用了这种方法,毕竟那是MS自家的产品,优化起来也容易一些。我这里要说的是另外一种解决方法,用Java实现一个服务器,在一个固定端口监听客户端请求,来执行给定的Java程序,客户端并不直接执行Java程序,只是将要执行的程序路径告诉服务器,实际服务器来执行,这样只需要服务器一次启动jvm,客户端并不需要启动jvm,速度就会很快。客户端可以用C甚至用python来实现。fsc利用的就是这个思想,fsc类似scalac,但它比scalac快多了,fsc并不直接编译,只是连接编译deamon进程,让它去编译。
通过这种方式来执行java,最有名的解决方案是
nailgun。但我并不喜欢它,因为它并不像我期望那样的工作,它对用户不透明。例如你在当前文件夹下有个HelloWorld的class,你执行"ng HelloWorld",结果它会说找不到HelloWorld类,因为服务器启动时HelloWorld类所在的目录并不是classpath。nailgun可以通过命令行来动态修改classpath路径,因此你可以在运行HelloWorld之前先将HelloWorld所在路径添加到nailgun服务器的classpath路径中去,添加时要指定绝对路径,"."实际上代表的是服务器启动时的路径。我觉得这些麻烦是不必要的,应当向客户端屏蔽“它实际上是在服务器端运行”这一事实,就好像它完全在本地启动jvm并执行一样。nailgun提供了一些额外的特性,包括给类起个别名,支持特定于nailgun的main启动方法,在这其中可以传递环境变量,我觉得这些都是没有必要的。
由于我不喜欢nailgun,并且我自认为找到了更好的实现方式(后来证明是错的),所以我就自己写了个
startup-java-fast。nailgun对每个客户端是使用一个单独的线程去运行,由于线程在同一个进程空间运行,不可能完全隔离各个客户端,另外在同一个进程中意味所有客户端共享环境变量。我最初的想法是使用fork()系统调用,fork()会创建一个新的子进程,由于fork的实现方式都是
copy-on-write,开销很低。fork的主要缺点在于java本身不提供对其的支持,我不得不借助jni来实现fork调用。我写了一个小程序来验证,证明行得通。另一个缺点就是fork只在unix下才有,在windows下没有相应的api,因为我基本不用windows,因此至少对我来说这不是问题。可是最终在实现时碰到很灵异的问题,这个问题在我之前写的验证程序中不存在。这是由于fork出来的子进程只会复制父进程中一个线程的内容,由于jvm明显使用了多线程(至少还有一个GC线程),这就导致子进程中的jvm工作不正常,出错时甚至没有任何错误提示。
由于使用进程方式失败,我只能使用线程模型,基本上走的是nailgun的路子,不同的是我致力于达到客户端的透明性。但由于线程模型的固有缺点,这个目标没有达到,我想到的主要有几点:
- 使用相对路径创建的文件是相对服务器端路径。虽然我设置了user.dir系统属性为客户端的当前路径,当由于创建文件是使用native调用,不理会user.dir系统属性。getAbsoluteFile()可以将相对路径转为绝对路径,它使用user.dir系统属性,这是用户所期望的,因此可以使用这种方式来绕过此问题。
- 不能再调用System的setIn/setOut/setErr/setProperties方法,因为我已经将这些值设置为ThreadLocal,这样每个客户端才会有独立的值。
- 调用多线程的客户端可能会有问题,尤其是当有个后台线程在运行时,这时客户主线程退出了,后台线程并不会退出,这会导致一些资源不能释放。我想到一种方法能够部分跟踪客户线程创建的其它线程,这样在主线程退出时可以回收这些线程,但我还没有实现。
startup-java-fast可以从这里
下载,先执行服务器,默认监听端口是0x2304:
$ java -jar sjfserver.jar
客户端我有两种实现,分别是C和python的,因为使用了对文件描述符的select,应该都不支持windows:
$ time sjf java HelloWorld
Hello World
real 0m0.017s
user 0m0.001s
sys 0m0.003s
对比python的hello程序:
$ time python hello.py
Hello World
real 0m0.045s
user 0m0.026s
sys 0m0.016s
可以看到用sjf来执行HelloWorld要比python快大约2倍。
分享到:
相关推荐
Java is the most popular programming language, according to the TIOBE index, and it is a very typical choice for running production systems in many companies, both in the startup world and among large...
1. **启动速度**:可以通过减少启动时加载的工作空间大小,禁用不需要的插件,或使用Eclipse的"Fast Startup"模式来加快启动速度。 2. **内存设置**:根据项目的规模调整Eclipse的JVM内存分配,避免因内存不足导致的...
3.1.13启动和关闭(Startup and Shutdown) 3.2 Ant 3.2.1 Ant 编辑器(Ant Editor) 3.2.2 Ant 执行时期(Ant Runtime) 3.3建置次序(Build Order) 3.4说明(Help) 3.4.1说明服务器(Help Server) 3.5自动更新(Install/...
3113启动和关闭(Startup and Shutdown)76 32 Ant77 321 Ant 编辑器(Ant Editor)78 322 Ant 执行时期(Ant Runtime)79 33建置次序(Build Order)81 34说明(Help)82 341说明服务器(Help Server)83 35自动更新(Install/...
3.1.13启动和关闭(Startup and Shutdown) 77 3.2 Ant 78 3.2.1 Ant 编辑器(Ant Editor) 79 3.2.2 Ant 执行时期(Ant Runtime) 80 3.3建置次序(Build Order) 82 3.4说明(Help) 83 3.4.1说明服务器(Help Server) 84 3.5...
3113 启动和关闭(Startup and Shutdown) 105 32 Ant 107 321 Ant 编辑器(Ant Editor) 107 322 Ant 执行时期(Ant Runtime) 109 33 建置次序(Build Order) 112 34 说明(Help) 113 341 说明服务器(Help Server) ...
在客户端,你需要在`D:\project\cms_project\ibssoft\JavaService\bin\org\ibs\config\datasource`路径下的`cms_db.properties`文件中,明确设置服务器的IP地址,以确保客户端能够正确连接到服务器进行数据通信。...
3.1.13啟動和關閉(Startup and Shutdown) 104 3.2 Ant 106 3.2.1 Ant 編輯器(Ant Editor) 106 3.2.2 Ant 執行時期(Ant Runtime) 108 3.3建置次序(Build Order) 111 3.4說明(Help) 112 3.4.1說明伺服器(Help Server) ...
- **快速视图(Fast View)**:快速查看文件或代码片段的上下文信息。 - **比较**:支持对文件或代码片段进行比较,有助于版本控制和代码审查。 - **历史记录**:记录用户的操作历史,便于追踪和恢复之前的更改。 - ...
- **3.1.13 启动和关闭(Startup and Shutdown)** - 配置启动和关闭时的行为。 - **3.2 Ant** - Ant是一个用于构建Java项目的工具,Eclipse提供了对Ant的支持。 - **3.3 构建顺序(Build Order)** - 控制项目...
startup founders, and CTOs concrete, industry-proven guidance and techniques for recruiting, hiring, and managing software engineers in a fast-paced, competitive environment. With so much at stake, ...
- **Java Dependencies**: Java runtime environment is required. - **Networking Configuration**: Proper network configuration to ensure connectivity between Impala daemons and other services. - **...
101 3.1.12搜尋(Search) 103 3.1.13啟動和關閉(Startup and Shutdown) 104 3.2 Ant 106 3.2.1 Ant 編輯器(Ant Editor) 106 3.2.2 Ant 執行時期(Ant Runtime) 108 3.3建置次序(Build ...
3.1.13 启动和关闭(Startup and Shutdown)...... 105 3.2 Ant ................. 107 3.2.1 Ant 编辑器(Ant Editor) ................ 107 3.2.2 Ant 执行时期(Ant Runtime) ............. 109 3.3 建置次序...
4. **容错机制**:Dubbo提供了多种容错策略,如Failover(重试其他服务器)、Failfast(快速失败)、Failsafe(失败安全)、Fallback(降级)等,增强了系统的健壮性。 回到“apache-dubbo-admin-0.4.0-bin-release...
23.1. Startup Failure 23.2. Customizing the Banner 23.3. Customizing SpringApplication 23.4. Fluent Builder API 23.5. Application Events and Listeners 23.6. Web Environment 23.7. Accessing Application...