JR 精品文章 - 你的程序有多大?
AD: jr (at) javaresearch.org


首页 | 动态 | 文章 | FAQ  | 新闻 | 下载 | 代码 | 工作 | 调查 | 术语 | 站点 | 图书 | 论坛 | 帮助 | 全部  

TOP | 交流 | 软件 | 专栏 | 开源 | 译/著 | 源码 | API  | 推荐 | FTP  | 积分 | 统计 | 搜索 | Blog | 我们  
首页 » 研究文集 » Java语言深入 评论此文章 发表评论     开始监控此文章 开始监控   加入收藏夹  加入收藏夹
你的程序有多大?
red-vampire 原创   更新:2008-04-18 22:41:52  版本: 1.0   

    你经常写一些有趣的小程序么?你想分发你的程序么? 你怎么保证目标机上有jre呢? 你打包一个? 一个jre几十兆,若是大工程,带个jdk也无所谓,如果你自己的类文件一共还没有1兆,就要带个几十兆的jre,你能接受么? 如果你想分发你的小程序,那么我们来进行jre瘦身吧! 看看我们的HelloWorld最小能多小。

    jre带的很多文件可能在你的程序里并不需要,或者你的程序只需要某个几兆大的jar里面的一个class。所以,理论上我们可以对jre进行减肥运动。把你不需要的jar和文件删掉,剩下的跟你的程序一起打个包。

下面以jdk5.0开发的一个HelloWorld为例来简单做个试验。

开发我们的Hello软件:

class Hello {
 public static void main(String[] args) {
  System.out.println("Hello World!");
 }
}

用java -verbose Hello 执行程序就能看到所有用到的class。当然,如果你的程序比较复杂,中间有条件跳转的话,一次执行可能并不能将所有的可能用到的class打印出来。这个不是大问题,你可以尝试别的办法来找出所有用到的文件。

1。把这些class找出来。java -verbose Hello>G:/jdkfit/Hello.list 

当然,用Runtime.exec("java -verbose Hello").getInputStream()来获得输出结果直接使用更好。

2。打个包。我们来写个程序来完成这个任务吧。执行下边这个Packager 程序。

3。拷贝一个jre,把我们自己打的jar覆盖jre的rt.jar,用这个jre执行java Hello。最好做个bat文件(我做了个run.bat)。 试着删除jre下的文件,看能不能run。直到最后,呵呵,只剩下这么几个了:

bin/java

bin/run.bat

bin/client/jvm.dll

lib/rt.jar (我们自己打的那个包)

lib/i386/jvm.cfg

共计大小:2.11兆

再来rar一下:1.123兆

呵呵 1.1兆的一个小程序包更加容易分发吧。

package cn.javadoc.jfit;

import java.io.BufferedReader;
import java.io.File;
import java.io.FileInputStream;
import java.io.FileOutputStream;
import java.io.IOException;
import java.io.InputStream;
import java.io.InputStreamReader;
import java.util.ArrayList;
import java.util.List;
import java.util.jar.JarOutputStream;
import java.util.zip.ZipEntry;

public class Packager {

 /**
  * @param args
  */
 public static void main(String[] args) throws Exception {
  File f = new File("G:/jdkfit/Hello.list");
  Packager pkger = new Packager();
  List ret = pkger.parseOutput(new FileInputStream(f));
  pkger.debugEnabled = true;
  pkger.pkgResources(ret, "G:/jdkfit/jar/Hello.jar");

 }

 private boolean debugEnabled;

 public List parseOutput(InputStream in) throws IOException {
  ArrayList ret = new ArrayList();
  BufferedReader reader = new BufferedReader(new InputStreamReader(in));
  String line = reader.readLine();
  while (line != null) {
   if (line.matches("\\[Loaded .* from .*")) {
    if (debugEnabled)
     System.out.println("Matches:" + line);
    ret.add(line.substring(8, line.indexOf(" from ")));
   } else {
    if (debugEnabled)
     System.out.println("UnMatches:" + line);
   }
   line = reader.readLine();
  }
  return ret;
 }

 public void pkgResources(List res, String fileName)
   throws IOException {
  File f = new File(fileName);
  if (!f.exists()) {
   f.createNewFile();
  }
  byte[] buf = new byte[1024];
  JarOutputStream out = new JarOutputStream(
    new FileOutputStream(fileName));
  for (String s : res) {
   s = s.replace('.', '/') + ".class";
   if (debugEnabled) {
    System.out.println("adding: " + s);
   }
   InputStream in = this.getClass().getClassLoader()
     .getResourceAsStream(s);
   out.putNextEntry(new ZipEntry(s));
   int w = in.read(buf);
   while (w >= 0) {
    out.write(buf, 0, w);
    w = in.read(buf);
   }
   in.close();
  }
  out.finish();
  out.close();
 }
}




版权声明   给作者写信
本篇文章对您是否有帮助?  投票:         投票结果:     18       0
作者其它文章: 作者全部文章
评论人:zhouwenguo112@163.com 发表时间: Sat Apr 19 09:54:22 CST 2008
java很强大[:@][w][kiss]
评论人:for_cyan 发表时间: Sat Apr 19 14:21:45 CST 2008
java应用程序如此,一个Web程序呢?如何精简才能最快?
评论人:Jacob-919 发表时间: Wed Apr 23 11:08:07 CST 2008
run.dat中是不是只用写上java Hello 就可以了?是不是应该把Hello.jar放在bin目录下。 
评论人:guoliang 发表时间: Thu Apr 24 16:55:53 CST 2008
java学习周期有点长
评论人:tuye3344 发表时间: Wed May 21 14:13:53 CST 2008
[good]

这个文章共有 5 条评论
主题: 从算法开始提高效率 上一篇文章
返回文章列表 返回〔Java语言深入〕
下一篇文章 主题: Java堆和栈 & StringBuilder效率探究


文字广告链接
        自主、快速定制基于JAVA的B/S业务系统          重量级企业在线自定义WEB报表平台
        Excel制表、零代码发布、打印、图表结合——快逸报表,免费、稳定、功能强大的java工具
        技术圈: 关于Java、dotNet、PHP、Ruby、奇客、Web2.0等更多资讯博客精选文章

关于 JR  |  版权声明  |  联系我们 

©2002-2006 JR 版权所有 沪ICP备05019622号