1. jre的运行时主要jar文件rt.jar都很大,这导致了用java做的桌面客户端程序很难发布绑定jre发布。这在很大程度上限制了java桌面软件 的分发。可是,jre并不是在所有的用户计算机上都有安装,即使安装了,也未必我们期望的版本。因此,对jre做精简,减少体积是有必要的。请你给出一个 方案,来说说如何给jre减肥,以方便我们的桌面程序绑定jre发布。并给出一个基本的实现。对这个实现的要求是:对于任意给定java程序A,应用你的 方案和实现,可以从一个完整的jre中,抽取这个程序A的必要部分,从而实现最小体积的发布。在本题中,要求你详述你的方案,并提交你实现的代码。

整个过程分为两步:

1. 找出程序依赖的所有class类文件,并整理出一个class依赖列表,具体步骤如下:

加入参数-XX:+TraceClassLoading, 启动桌面程序并且重定向console流到一个文件比如classdepenency.txt.
  然后对程序做一个完整的回归测试,确保所有的功能点都已经用到了,目的是为了完整的加载所有的依赖。
  因为有些依赖class可能是运行时期通过反射或者Class.forName()来加载的,这些类只有在代码被运行的时候classloader才会加载对应的依赖。
  程序测试完毕后,用编辑工具比如notepad++对classdepenency.txt做一个简单的筛选,去掉与classloading无关的console信息。

只留如下所示的classloader加载rt.jar中类的信息。
  
[Loaded java.util.logging.LogManager$2 from F:Program FilesJavajdk1.7.0_51jrelibrt.jar]
[Loaded java.util.Collections$EmptyEnumeration from F:Program FilesJavajdk1.7.0_51jrelibrt.jar]
[Loaded java.util.EventObject from F:Program FilesJavajdk1.7.0_51jrelibrt.jar]
[Loaded java.beans.PropertyChangeEvent from F:Program FilesJavajdk1.7.0_51jrelibrt.jar]
[Loaded sun.util.logging.PlatformLogger from F:Program FilesJavajdk1.7.0_51jrelibrt.jar]

2. 写个小程序从JRE里面的rt.jar抽取出上一步筛选后的classdepenency.txt文件里记录的所有类.下面是程序的代码.

01 package test;
02 import java.io.BufferedReader;
03 import java.io.FileInputStream;
04 import java.io.FileOutputStream;
05 import java.io.InputStream;
06 import java.io.InputStreamReader;
07 import java.util.ArrayList;
08 import java.util.List;
09 import java.util.jar.JarEntry;
10 import java.util.jar.JarFile;
11 import java.util.jar.JarInputStream;
12 import java.util.jar.JarOutputStream;
13  
14  
15 public class ReduceJRE {
16  
17     public static void main(String[] args) throws Exception {
18         String mainJar = null;
19         String classDenpdencyFile = null;
20         if(args!=null && args.length==2)
21         {
22             mainJar = args[0];
23             classDenpdencyFile = args[1];
24         }
25         else {
26             mainJar = "F:Program FilesJavajre7librt.jar";
27             classDenpdencyFile = "F:Program FilesJavajre7libclassdepency.txt";
28         }
29         ListdepencyClass = new ArrayList();
30         BufferedReader br = new BufferedReader(new InputStreamReader(new FileInputStream(classDenpdencyFile)));
31         String templine = br.readLine();
32         // load all the dependency class and store them in a array list;
33         while(templine!=null) {
34             int end = templine.lastIndexOf("from");
35             int begin = templine.lastIndexOf("[Loaded")+7;
36             String className = templine.substring(begin,end).replace(".", "/").trim();
37             depencyClass.add(className);
38             templine= br.readLine();
39         }
40         JarFile zipIn = new JarFile(mainJar);
41         InputStream readin = null;
42         JarOutputStream jos = new JarOutputStream(new FileOutputStream("rt.jar"));
43         JarInputStream  jis = new JarInputStream(new FileInputStream(mainJar));
44         JarEntry entry = jis.getNextJarEntry();
45         while(entry!=null) {
46             String name = entry.getName();
47             //remove the .class suffix.
48             name = name.substring(0,name.lastIndexOf("."));
49             if(depencyClass.contains(name)) {
50                 //put an entry record and write the binary data
51                 jos.putNextEntry(entry);
52                 readin = zipIn.getInputStream(entry);
53                 byte[] temp = new byte[4096];
54                 int count = readin.read(temp);
55                 while (count != -1) {
56                         jos.write(temp, 0, count);
57                         count = readin.read(temp);
58                 }
59                 readin.close();
60             }
61             entry = jis.getNextJarEntry();
62         }
63         jis.close();
64         jos.close();
65     }
66 }
1 运行下面Java命令,来生产简化版的rt.jar
1 java test.ReduceJRE  "F:\Program Files\Java\jre7\lib\rt.jar"  "F:\Program Files\Java\jre7\lib\classdepency.txt"

会在当前目录下生产一个精简版的rt.jar,用这个简化的rt.jar替代原来的rt.jar, 然后绑定JRE和桌程序一起发布。

这里有个需要主意的事项就是内部类的class文件是否需要特殊处理, 结论是不需要特殊处理.

因为我们做了完全的回归测试,用到的所有类(包括内部类),都已经加装了。

如果发现一个类有多个内部类而classdepenency.txt里面却显示只有一个内部类被加装,那是因为非静态内部类,只有在用到的情况下,才会加装。

既然我们的回归测试时都没有用到它,那么就说明是不需要的,因此内部类也不需要特殊考虑.

2.这里给出一个gc输出,要求给出一个你认为最可能的启动JVM参数,并说明为什么?

Heap
 def new generation   total 6464K, used 115K [0x34e80000, 0x35580000, 0x35580000)
  eden space 5760K,   2% used [0x34e80000, 0x34e9cd38, 0x35420000)
  from space 704K,   0% used [0x354d0000, 0x354d0000, 0x35580000)
  to   space 704K,   0% used [0x35420000, 0x35420000, 0x354d0000)
 tenured generation   total 18124K, used 8277K [0x35580000, 0x36733000, 0x37680000)
   the space 18124K,  45% used [0x35580000, 0x35d95758, 0x35d95800, 0x36733000)
 compacting perm gen  total 16384K, used 16383K [0x37680000, 0x38680000, 0x38680000)
   the space 16384K,  99% used [0x37680000, 0x3867ffc0, 0x38680000, 0x38680000)
    ro space 10240K,  44% used [0x38680000, 0x38af73f0, 0x38af7400, 0x39080000)
    rw space 12288K,  52% used [0x39080000, 0x396cdd28, 0x396cde00, 0x39c80000)

首先,这是一个client JVM生产的heap信息,因为加入-Server后得到的分代的标识都和例子很不一样.
但是对于很多非服务器的桌面系统默认运行的时候都是-client,所以不能确定是否指定了-client,只知道是运行在client JVM中.

对于Tenured Generation    当前大小=0x36733000-0x35580000=18124K=17.69921875M   总大小=0x37680000-0x35580000=33M
对于def new generation    新生代的内存总是一次性申请完的, 所以当前大小总是和总大小相等的,总大小=0x35580000-0x34e80000=7M

新生代:老年代=7:33 不是一个能够使用-XX:NewRatio来按比例分配的结果.

JVM 默认的比例是 新生代:老年代=1:2, 也和样例不符合,所以也不是默认值.

推测是加入了-Xmn7M来控制新生代,因此堆的最大值就是-Xmx40M。

对于老年代:初始大小=0x35d95758-0x35580000=8M,所以-Xms=15M

在新生代内部 s0:s1:eden=1:1:8 符合-XX:SurvivorRatio=8的分配结果,但是这个也是新生代内部默认的分配比例,所以不能确定是否指定了-XX:SurvivorRatio=8

对于Perm gen , 总大小=0x38680000-0x37680000=16M,初始大小=0x3867ffc0-0x37680000=15M

样例是GC的详细信息,所以肯定使用了 -XX:+PrintGCDetails

总结如下: 方括号里的参数是不确定的,可有可无.

-XX:+PrintGCDetails  -XX:MaxPermSize=16M  -XX:PermSize=15M -Xmx40M -Xms15M -Xmn7m  [-XX:SurvivorRatio=8]  [-client]

JVM培训作业第二周的更多相关文章

  1. bug终结者 团队作业第二周

    bug终结者 团队作业第二周 我们小组选取游戏"开心消消乐",回答问题: 1. 此类软件是什么时候开始出现的, 这些软件是怎么说服你(陌生人)成为他们的用户的? 他们的目标都是盈利 ...

  2. 《团队作业第二周》五小福团队作业——UNO

    <团队作业第二周>五小福团队作业--UNO 一.修改完善上周提交的需求规格说明书 THE FIRST改变 首先:我们组的博客无小组分工及占比,这是第一个问题,当时我们在写博客的时候由于很多 ...

  3. 2017-2018-2 1723《程序设计与数据结构》第九周作业 & 第二周结对编程 总结

    作业地址 第九次作业:https://edu.cnblogs.com/campus/besti/CS-IMIS-1723/homework/1878 (作业界面已评分,可随时查看,如果对自己的评分有意 ...

  4. 绿洲作业第二周 - Y3每日中文学习任务清单

    1. 本周仍是古诗学习周,老师已在“最美诵读”上布置本周需完成的任务,请孩子在“最美诵读”小程序中,结合老师发的学习任务清单,合理安排时间进行学习.如果孩子另有学习安排,可在周日(2.23)23:59 ...

  5. 团队作业-第二周-SRS文档

    移动课堂点名的用例图:

  6. 团队作业—第二周—SRS

    一.系统整体用例图: 二.用户用例图: 三.医院用例图:

  7. FJUT寒假作业第二周C题解(位运算)

    题目来源:http://210.34.193.66:8080/vj/Contest.jsp?cid=161#P2 题意比较好理解.如果直接按题目要求一步一解.一定超时.作为一个懒人也不会这么暴力一个肯 ...

  8. FJUT寒假作业第二周G题解快速幂

    题目来源:http://210.34.193.66:8080/vj/Contest.jsp?cid=161#P6     题意:求n个数字的乘积对c取摸.主要就是有快速幂扩展到广义幂的过程. 首先题目 ...

  9. Linux内核分析作业第二周

    操作系统是如何工作的 <Linux内核分析>MOOC课程http://mooc.study.163.com/course/USTC-1000029000 一.函数调用堆栈 1.计算机工作三 ...

随机推荐

  1. CSS3选择器(三)之伪类选择器

    伪类选择器对于大家来说最熟悉的莫过于:link,:focus,:hover之类的了,因为这些在平时中是常用到的伪类选择器,那么先和大家一起简单总 结一下CSS中常用的伪类选择器的使用方法,最后把重心放 ...

  2. Spring整合Quartz实现持久化、动态设定时间

    一.spring整合 网上一搜有很多整合的方式,这里我采用了其中的一种(暂时还没有对其他的方法研究过). 对于spring的整合其中的任务,spring提供了几个类.接口(这些类都实现了Job接口): ...

  3. for循环计算游戏通关分数

    一个游戏1到20关是成绩是自身关卡数的成绩,21-30每关10分,31-40每关20分,41-49每关30分,50关100分.输入一个关数求成绩 代码如下: <!DOCTYPE html PUB ...

  4. 关于纯css布局的概况

    用一些常用的手法来表现感情或者论证问题,这在XHTML中就是用特定的元素来完成一些常见的信息组织.下面就是信息组织形式与元素的对应列表. img 作为内容的图片是一定要放到img里面的,这没有更好的选 ...

  5. 用Editplus开发HTML

    准备工作 设置Editplus默认的打开浏览器为系统默认浏览器 取消Editplus的临时缓存文件 ☆ 设置不生成临时文件 这里的临时文件,指的是.bak文件,当你在Editplus下修改任意一个文件 ...

  6. 【ArcGis for javascript从零开始】之一 ArcGis加载天地图

    最近做项目需要用到ArcGis来进行数据展示和数据分析.以前从来没有接触过与Gis有关的东西,一切需要从头开始学.没有时间从头系统地学习了,只能用到哪个学习哪里了,本系列只是对学习的路径进行记录.Ar ...

  7. linux 防火墙设置

    防火墙的基本操作命令: 查询防火墙状态:[root@localhost ~]# service iptables status<回车> 停止防火墙:[root@localhost ~]# ...

  8. WITCH CHAPTER 0 [cry] 绝密开发中的史克威尔艾尼克斯的DX12技术演示全貌

    西川善司的[WITCH CHAPTER 0  cry]讲座 ~绝密开发中的史克威尔艾尼克斯的DX12技术演示全貌   注:日文原文地址: http://pc.watch.impress.co.jp/d ...

  9. PHP面向对象程序设计的61条黄金法则

    PHP面向对象程序设计的61条黄金法则   你不必严格遵守这些原则,违背它们也不会被处以宗教刑罚.但你应当把这些原则看成警铃,若违背了其中的一条,那么警铃就会响起 . ----- Arthur J.R ...

  10. apache磁盘缓存配置

    确保mod_cache和mod_disk_cache是开启的 配置如下: CacheDefaultExpire 86400 #失效时间,单位秒CacheEnable disk /      #缓存路径 ...