Send As SMS

2005-07-28

新的调试技巧

在eclipse中内建了很强的代码调试功能,其中有一个Conditional Breakpoint的功能实际上还可以用来作为另外的用途:

public void someMethod(String argument) {
String a = getSomeValue();
String b = getSomeOtherValue();
// conditional breakpoint on this line

}
然后我们可以在 someMethod 中加入如下的条件断点:

System.out.println(argument);
System.out.println(a);
System.out.println(b);
return false;

这样的话,这个断点会让代码每次运行时都打印一些额外的信息,但却不会导致程序的停顿。这可以让我们在不修改代码的情况下,增加一些调试的代码,让其在程序中得以运行。

类似的另外一个功能是在Display窗口中进行evaluation/run/display等操作,也可以执行我们的一些新的代码,比较灵活,但难以自动化的让其执行。

2005-07-27

CPU的一点想法

1、超线程结构设计。
     整个CPU有N套流水线、寄存器和执行单元,可以同时执行多个线程。为了简化CPU结构,我们不再单条流水线内做太多优化,而是一个近可能简单的RISC 结构。在一条流水线上,不采用超标量的技术和复杂的预测、并发支持。近可能的保证大部分的RISC指令可以在一个周期内完成。
通过多线程来提高整个CPU执行单元的并发能力。

2、寄存器设计
     32个64位通用寄存器,32个64位浮点寄存器。在指令中,一个寄存器近占5位。部分寄存器保留作为特殊用途,如0/1等常数,时钟周期计数器等。
     寄存器数量不用太多(因为每个线程内的并发要求很低),X86近提供8个通用寄存器都可以工作得很好。

3、指令设计。
     大部分的指令具有非常一致的规格,32位,3个寻址部分,遵循RISC规则,将访问内存的操作独立到load/store指令中。也支持复杂的指令,复杂 指令将由共享的执行单元来完成,比如说,可以有一个MMX的执行单元、一个3D的执行单元。而RISC指令的执行单元则基本上每个线程独立的。这样既可以 使得具有很高的通用计算能力,也可以根据需要扩展CISC执行单元。CISC执行单元不再有相应的寄存器。

4、堆栈设计。
    每个执行线程内有一个128字的堆栈Cache,对基于SP寄存器的操作,首先在此Cache中进行命中。这可以让CPU队大部分的local数据以寄存 器的方式进行直接访问。堆栈Cache是与内存同步的,随着函数的调用、返回,CPU自动的进行Cache的维护。
    
5、Cache。

6、系统采用64位的统一的地址空间,支持虚拟内存,但虚拟内存仅仅是将外部内存作为物理内存的一个后备,而不再为不同的任务分割不同的地址空间。每一个 任务都有一个段寄存器,所有的偏移是相对于该段寄存器的。系统共享一个统一的TLB(逻辑地址-物理地址映射)。每一个段的大小不可变化。对小任务,可以 是4M,16M,64M,256M,1G, 4G, 16G, 64G,256G,1T等值。缺省的是256M,可以满足大部分的任务要求。通过多个任务的协作来提高整个系统的能力。

7、对Java虚拟机的支持。
绝大部分的Java指令是通过软件JIT的方式编译成为RISC指令执行的,但系统也提供一些高层的服务,这些服务是放在一个称之为JVM的执行单元中,可以在Java指令编译时选择使用。CPU上可以提供一定数量的Java执行单元。

2005-07-25

对XML处理技术的一些想法

1、Buffer - DOM - AOM 的三层结构
  • XML Buffer:对应于一个XML的字符流存储。XML Buffer的一个优势包括:对于大型的XML,可以采用压缩的方式对XML进行处理,从而减少所需的内存开销。或者直接使用文件系统作为外部存储,从而 可以更少的使用内存。与此同时,XML Buffer在接口的层面上提供了对XML的随机访问。并且可以升级到使用DOM来访问XML。
  • DOM:最为经典的XML API。不过,由于基于XML Buffer,DOM可以采用Lazy化技术,只对活动的DOM对象创建活动的对象,而对不活动的对象可以钝化到XML Buffer中,或者根据需要而激活。这样做的优势可以支持非常快速的Parse,在Parse的过程中无须建立起全部的对象,部分的深层次的对象可以按 需激活。此外,也可以对于大型的文档,使用较小的footprint来存储DOM。Lazy访问即提供了对DOM的透明访问(Client API仍然采用标准的DOM API来访问XML,不需要进行变化)。此外,DOM还可以升级为AOM,提供语义层的访问。
  • AOM:将DOM映射成为Java的对象模型,从而Java可以使用类型化的API对XML进行访问。JAXB2是这种映射模型的一个反映。 虽然JAXB2采用POJO来映射XML,带来了相当的灵活性。但基于接口的映射仍然是非常有价值的,其中,最为重要的是,可以对POJO进行的变化可以 直接的(透明的)反映到DOM、Buffer层面中。AOM虽然提供了强的Java映射处理,但我们仍然不希望失去DOM的动态性。比若说,XML可能进 行扩展,而AOM则无法及时地反映该变化。
2、XML Schema
在XML DOM中,可以获取相应的Schema元信息,例如,一个XML Element有一个对应的XML Schema Type,就像Java对象有相应的JavaClass一样。
AOM的映射信息通过JAXB2的annotation信息标注(可以从class中恢复出对应的Schema信息),当一个Schema对象被映射成为 一个interface时,可以使用bytecode生成的技术自动的生成一个相应的类来。这个生成的类可以实现对DOM的同步。同样,当DOM对象发生 变化时,AOM也可以透明的获得同步。


2005-07-22

OpenOffice文档格式分析

最近,在看一下OpenOffice的一些资料,openoffice使用XML作为文档的存储格式,一个ODT文件实际上是一个标准的zip文件,其中主要包括:
  • meta-inf/manifest.xml 描述zip文件中的每一个文件及其mime类型
  • content.xml 主文档内容,
  • styles.xml 文档中的样式表。在content.xml中没有存储字体、颜色等信息,这些全部通过style来引用在此中定义的格式。
  • meta.xml 文档的主要元信息,如作者、keywords等
  • setting.xml 一些设置信息,例如打印设置、显示设置等。
其中最为主要的应该是content.xml和styles.xml了。这些XML都由oasis组织负责进行规范定义,因此,openoffice的文档格式是存在定义良好的标准的,这也为其进一步的发展提供了很好的基础。

我在分析OpenDocument-v1.0-os.sxw(就是OASIS对OpenOffice文档XML定义的文档)进行分析时,发现:这个sxw 文档大小为434K,content.xml文件大小为:4.58m, 整个文档长达706页。把这个文档另存为Word文档在MS Office2003中打开时,文件大小变为3.86M,压缩后为607K。在性能上,OpenOffice打开此文档大约需要6s时间,CPU及内存消 耗很小,而word打开此文档的时间相当长,内存耗费巨大,而且,在后续的操作过程中,反映非常的慢,动不动就CPU紧张,虽然我的机器有1G的ram, 但可用性大大降低。

那么究竟是什么原因让openoffice在处理大文档时具有如此好的性能呢?我没有研究openoffice的源代码,不知道其内部的结构和处理逻辑, 因此,这里的一些想法纯粹是我个人的一些想法。就是说,如果让我来设计,应该如何才能使用很小的内存开销,但又能够快速的对文件进行处理呢?

Level1: fragged - (compressed)- xml -stream :用来存储XML的字节流,采用分块的方式,每一块保存XML的一部分。Level 1 提供了对XML的随机访问的能力。由于实际上,大部分的XML操作都是在一个区域内进行,因此,提供随机访问的能力,将使得XML处理更为方便。
采用分块的形式进行存储,通过算法进行调整,每一块的大小尽可能平衡。当块不经常访问时,整个快可以被压缩。而当块需要随机访问时,又可以解压缩。 Level1 实际上比较适合于作为一种中间存储格式,在文档编辑的过程中,经常需要保存当前的快照,如果每次都保存成zip-xml的话,效率会很低。

Level 2: Lazy DOM:在Level1的基础之上,构建整个文档的DOM。建议采用类似于JDOM的DOM结构(不再处理一些XML的语法甜品,如CDATA、 &扩展等),不过Lazy DOM中的每一个节点并不完整的构建出整个的DOM在内存中,而是根据需要创建DOM节点,在不需要时,自动的进行垃圾回收。(如果我们可以进一步自己的 管理对象的内存,例如重用旧的对象的话,可能效果会更好)。由于在文档浏览、编辑过陈各种,总是在一个较小的活动区域内进行,因此,Lazy DOM将使得我们无须尽力整个的DOM,而尽可能的使用更小的内存。

Level 3: Application Object Model:DOM是完全面向XML的,优势是天然的XML一致,几乎没有距离,不会损失XML信息(但我们还是会做出一些XML的限制,例如不使用 CDATA、&替换等),但不便于进行应用处理。在OO的世界中,我们应该提供一个AOM层,将DOM映射成为应用的对象。JAXB2 是一种候选的技术,但我们仍然希望 AOM 能够与 DOM 相结合使用。建立在LazyDOM的基础之上,整个AOM也可以是Lazy的。从而仅按需创建AOM对象。

Level 4: Cached Runtime Object。以Writer文档为例,如果只基于Lazy AOM,那么,当处理用户需要调准到第#页时,或者跳转到第#章时,是否需要激活整个DOM,来发现第#页的信息呢?如果是这样的话,一定会影响效率的。 如果我们可以预先计算所有的Page,把Page的信息Cache起来(但是在Cache中不应该直接引用DOM,而应该是一个Ref,这个Ref并不防 止相应的DOM可以Lazy化,但又可以在需要的时候对其激活,并且最佳的实现API级的透明化),那么,在处理这种操作时,我们可以直接从该Page对 象出发,显示此页面。这里的一个关键的技术是透明化的访问和DOM对象的Reference技术。(从sxw文件的存储来看,其中包括一个layout- cache的二进制文件,应该就是做这个用途的)

以上面例子来看,一个4.58M的Content.xml,假设:
1、fragged-stream 大约为1M(或者干脆使用不压缩的格式,但存储在磁盘中,并不占用内存)
2、Lazy DOM:一般的,一个文档的活动DOM集大约在512K-1M的范围。
3、AOM:跟LazyDOM类似。
4、其他:可以跟据需要,一般是一个相对估计的内存开销,大约1-2M。
也就是说,理论上,我们只需要4-5M的ram,就可以进行一个如此巨大的文档的编辑活动了。

一个比较好的试验方式是:使用Java做一个模拟性的开发,以展示为主题,然后逐步过渡到编辑工具上,说不定可以成就一个JavaOffice呢。说实在的,Java世界真的需要这样的一个Office,而Office移植到Java也一定有更好的前途。

2005-07-15

基于OpenOffice的报表想法

1、在OpenOffice设计时,采用OpenOffice的排版和布局功能,将其作为一个文档容器,在其中嵌入我们的元素,例如:
公式字段、表格等。
2、在作为报表执行时,将其作为一个模板的语言。

优势:我们将自动拥有一个强大的排版系统。
缺点:对OpenOffice的整合能力还没有清楚的认识,是否方便的将我们的功能潜入进去。

SpreadSheet也是一个很强大的报表工具。