Java虚拟机

2024-05-07

Java虚拟机(精选8篇)

Java虚拟机 第1篇

按照编译原理的观点把内存分配策略划分为3种:静态的、栈式的和堆式的。静态存储分配是指在编译时就能确定每个数据目标在运行时刻的存储空间需求, 因而在编译时就分配固定的内存空间, 这种分配策略要求程序代码中不允许有可变数据结构 (比如可变数组) 的存在。Java语言是面向对象, 并且具有多态性的特点, 因此JVM选用动态内存分配策略:堆和栈。

1 堆和栈

在函数中定义的一些基本类型的变量和对象的引用变量都在函数的栈内存中分配。

当在一段代码块定义一个变量时, Java就在栈中为这个变量分配内存空间, 当超过变量的作用域后, Java会自动释放掉为该变量所分配的内存空间, 该内存空间可以立即被另作他用。

堆内存用来存放由new创建的对象和数组。在堆中分配的内存, 由Java虚拟机的自动垃圾回收器来管理。在堆中产生了一个数组或对象后, 还可以在栈中定义一个特殊的变量, 让栈中这个变量的取值等于数组或对象在堆内存中的首地址, 栈中的这个变量就成了数组或对象的引用变量。引用变量就相当于是为数组或对象起的一个名称, 以后就可以在程序中使用栈中的引用变量来访问堆中的数组或对象。

Java是自动管理栈和堆, 程序员不能直接地设置栈或堆。

Java的堆是一个运行时数据存储区, 类的对象从中分配空间。对象通过new、newarray等方式建立, 不需要程序代码来显式地释放。堆是由垃圾回收来负责的, 堆的优势是可以动态地分配内存大小;缺点是, 存取速度较慢。

栈的优点是, 存取速度比堆要快, 仅次于寄存器。栈数据可以共享;缺点是, 存在栈中的数据大小与生存期必须是确定的, 缺乏灵活性。栈中主要存放一些基本类型的变量 (int, short, long, byte, float, double, boolean, char) 和对象句柄。

栈有一个重要特点, 就是存在栈中的数据可以共享。假设定义:

编译器先处理int a=3;首先会在栈中创建一个变量为a的引用, 然后查找栈中是否有3这个值, 如果没找到, 就将3存放进来, 然后将a指向3。接着处理int b=3;在创建完b的引用变量后, 因为在栈中已经有3这个值, 便将b直接指向3。这样, 就出现了a与b同时均指向3的情况。这时, 如果再令a=4;那么编译器会重新搜索栈中是否有4值, 如果没有, 则将4存放进来, 并令a指向4;如果已经有了, 则直接将a指向这个地址。因此a值的改变不会影响到b的值。要注意这种数据的共享与两个对象的引用同时指向一个对象的这种共享是不同的, 因为这种情况a的修改并不会影响到b, 它是由编译器完成的, 它有利于节省空间。而一个对象引用变量修改了这个对象的内部状态, 会影响到另一个对象引用变量。

2 String类对象举例说明

String是一个特殊的包装类数据。可以用:

两种的形式来创建, 第一种是用new () 来新建对象的, 它会在存放于堆中。每调用一次就会创建一个新的对象。

而第二种是先在栈中创建一个对String类的对象引用变量str, 然后查找栈中有没有存放“abc”, 如果没有, 则将“abc”存放进栈, 并令str指向“abc”, 如果已经有“abc”, 则直接令str指向“abc”。

比较类里面的数值是否相等时, 用equals () 方法;当测试两个包装类的引用是否指向同一个对象时, 用==, 下面用例子说明上面的理论。

因此用第二种方式创建多个“abc”字符串, 在内存中其实只存在一个对象而已。这种写法有利于节省内存空间。同时它可以在一定程度上提高程序的运行速度, 因为JVM会自动根据栈中数据的实际情况来决定是否有必要创建新对象。而对于String str=new String (“abc”) ;的代码, 则一概在堆中创建新对象, 而不管其字符串值是否相等, 是否有必要创建新对象, 从而加重了程序的负担。

尤其需要注意的是:在使用诸如String str=“abc”;的格式定义类时, 总是想当然地认为, 创建了String类的对象str。事实是对象可能并没有被创建, 而可能只是指向一个先前已经创建的对象。只有通过new () 方法才是每次都创建一个新的对象。

3 结束语

每一个Java应用都唯一对应一个JVM实例, 每一个实例唯一对应一个堆。应用程序在运行中所创建的所有类实例或数组都放在这个堆中, 并由应用所有的线程共享。Java中分配堆内存是自动初始化的。Java中所有对象的存储空间都是在堆中分配的, 但是这个对象的引用却是在栈中分配, 也就是说在建立一个对象时从两个地方都分配内存, 在堆中分配的内存实际建立这个对象, 而在堆栈中分配的内存只是一个指向这个堆对象的指针 (引用) 而已。

摘要:Java把内存划分为堆和栈。介绍了堆和栈的区别, 并以String类对象为例说明它们在内存分配中的不同, 及对程序编写的影响。

关键词:JVM,堆,栈,string类

参考文献

[1]任哲.Java技术应用基础——对象.模式.虚拟机[M].北京:机械工业出版社, 2009.

[2]Java虚拟机内存分配与回收机制[EB/OL].http://www.yqdown.com/chengxukaifa/Java/11580.htm.

[3][美]BILL VENNERS.深入Java虚拟机[M].北京:机械工业出版社, 2003.

Java虚拟机 第2篇

课程设计报告

目:

ATM柜员机

业:

信息与计算科学

号:

名:

指导教师:

成绩:

2010 年 12 月 10 日

目 录

1课程设计研究背景及意义.......................................2 2 课程设计题目描述和基本功能设计要求...........................2 3 系统需求分析.................................................2 3.1 功能需求分析............................................2 3.2 其他需求分析............................................3 4 系统设计.....................................................3 4.1 总体设计................................................3 4.2 ATM柜员机界面设计......................................4 4.3 各功能模块设计..........................................5

4.3.1 登陆页面模块设计................................5 4.3.2 选择服务模块设计................................6 4.3.3 取款模块设计....................................7 4.3.4 修改密码模块设计................................8 4.3.5 查询余额模块设计................................9 4.3.6 退卡模块设计....................................9 4.4 异常处理情况说明.......................................10 5 系统实现与测试..............................................10 6 课程设计总结................................................13 6.1 遇到的问题及解决办法...................................13 6.2 心得体会...............................................14 参考文献......................................................14 附录(源码)..................................................14

1课程设计研究背景及意义

这次课程设计是通过JAVA编程来实现ATM柜员机的功能。以前,人们用手算取钱,不管从方便的角度还是速度的角度来看都不及现在。电子技术的不断发展使得ATM自动化的功能不断完善。在二十一世纪的今天,ATM柜员机是人们生活中重要的工具,所以,对ATM柜员机的研究的课程设计具有重大意义。

这次课程设计的主要目的是结合面向对象程序设计课程,培养我们面向对象开发的思维,初步了解软件开发的一般流程,提高用JAVA编程的实际动手能力并增强大家对面向对象的了解。这次课程设计的主要内容是独立用JAVA语言开发一个小的应用程序。课程设计题目描述和基本功能设计要求

本次设计的ATM柜员机主要是由各个Windows窗口组成,它是由登录页面、选择服务、取款、查询余额、修改密码和退卡等功能。它的各种按钮的事件和功能可以简单的模拟ATM柜员机的要求。组员分工:

组长(单焱): 负责分配其他组员的任务,构建需求分析,系统实现及异常处理情况,调试程序等,把握ATM柜员机的整体布局。

组员1(刘星):负责登陆界面模块,选择服务模块及退卡模块,编写相应代码。组员2(王玲玲):负责取款、修改密码、查询余额模块,编写相应代码。系统需求分析 3.1 功能需求分析

本ATM柜员机的主要功能如下所述:

要求使用图形用户界面。当输入给定的卡号和密码(初始卡号为000000和密码为123456)时,系统能登录ATM柜员机系统,用户可以按照以下规则进行:

 查询余额:初始余额为50000元

 ATM取款:每次取款金额为100的倍数,总额不超过5000元,支取金额不允许透支。

 ATM存款:不能出现负存款。

 修改密码:只有旧密码正确,新密码符合要求,且两次输入相同的情况下才可以成功修改密码。

3.2 其他需求分析

(1)性能描述

实时性好、灵活性强、易于不同年龄阶段的人操作。(2)设计约束 开发工具:Eclipse3.2.运行环境:Windows 2000以上。(3)界面要求

以Windows窗口形式显示,标题栏为ATM柜员机名称,右上角有最小化按钮、最大化按钮、关闭按钮,不同的窗口中有不同的按钮和选择菜单。系统设计 4.1 总体设计

本次设计的ATM柜员机主要是由登录页面模块还由选择服务模块组成,其中选择服务模块又由取款模块、查询余额模块、修改密码模块、退卡模块组成。如图:

图1

ATM功能结构示意图

4.2 ATM柜员机界面设计

一个系统的界面应该要简单明了,当然样式美观就更好了。本次设计的界面主要是由窗体组成,操作简单。而每一个窗口则执行相应的功能。

一个系统界面的好坏直接影响到用户的操作,界面设计要求样式美观、简单明了、方便易操作。界面主要分为窗体、菜单、按钮和文本输入框几个部分,分别执行相应的操作。

(1)窗体的设计

窗体整个框架使用Frame类构造,Frame有自己的外边框和自己的标题,创建Frame时可以指定其窗口标题,我创建的窗口标题是各个不同功能的模块的名字,比如说查询余额,还有取款等。相应源代码为:WindowBox(String s){super(s);}、Selection(String s,Account act){ } 向Frame窗口中添加组件使用add()。例如:button1 = new Button(“存款”);

p1.add(button1);this.add(p1);super(s);每个Frame在其右上角都有三个控制图标,分别代表将窗口最小化、窗口最大化和关闭的操作,其中最小化和最大化操作Frame可自动完成,而关闭窗口操作实现需要书写有关的代码,在我的程序中我采用的是对WINDOWS_CLOSING事件做出响应,调用dispose()方法关闭窗口。Frame也可以引发WindowsEvent类代表的窗口事件。相应源代码为:

addWindowListener(new WindowAdapter()//窗口侦听器,以从此窗口接收窗口事件 {public void windowClosing(WindowEvent e)//处理窗口关闭事件

{ System.exit(0);} });}(2)窗体的主要结构的设计(网格布局)

我所设计的窗口的主要结构的特点就是每个窗口都对应着一个特定的功能。比如说报各种各样的错,还有各种查询余额、取款、选择服务等,所以它们都是由各种按钮和文本框,标签组成的,而联系各个窗体成为一个整体的就是各个按钮的监听事件。所以整个设计就趋向简单化了。

为了定义各个按钮所对应的命令和操作,首先需要将各个按钮注册给实现了动作事件的监听接口ActionListener的监听者,然后为监听者定义actionPerformed(ActionEvent e)方法,在这个方法中调用e.getSource()或e.getActionCommand()来判断用户点击的菜单子项,并完成这个菜单子项定义的操作。

4.3 各功能模块设计 4.3.1 登陆页面模块设计

与ATM柜员机打交道比较多的,也是大家对安全比较关心的问题:密码。所以第一个界面就是要输入密码和卡号才能继续服务。

我定义了文本框累的对象tf1,tf2。抓药是用于输入单行的文本;文本区调用public String getText()方法,获取用户想要的字符串。用来判断输入的密码和卡号是否正确,如果不正确的话,则弹出密码或卡号错误的警告框,并用dispose()关掉窗口。此模块相应的部分源代码为:

public void actionPerformed(ActionEvent e){

Account act;

String card;

String pwd;

act=new Account(“000000”,“Devil”,“123456”,50000);//初始化

/*选择各种服务*/

if(e.getSource()== button1){

String number1,number2;

number1=tf1.getText();

number2=tf2.getText();

/*判断密码和卡号是否正确*/ if((act.get_Code().equals(number1))&&(act.get_Password().equals(number2))){

dispose();

/*卡号和密码都正确则进入功能选择窗口*/

Selection s = new Selection(“选择服务”,act);

}else{

dispose();

JOptionPane.showMessageDialog(null, “您输入的卡号或密码不正确,请核实后再确定”,“消息!”, JOptionPane.INFORMATION_MESSAGE);

new WindowBox(“登录界面”);

}

}

/*退卡*/ if(e.getSource()==button2){

dispose();

JOptionPane.showMessageDialog(null, “谢谢使用!”, “消息!”,JOptionPane.INFORMATION_MESSAGE);System.exit(0);

} } 4.3.2 选择服务模块设计

在选择服务模块中,有各种ATM的服务功能,只要用户在该界面中选择按钮,它就会弹出各个相应的界面。每一个按钮都有监听器,在选择了按钮后,java.awt.event中的ActionEvent类创建一个事件对象,并将它传递给方法public void actionPerformed(ActionEvent e)中的参数e,监视器就会知道所发生的事件,对此事件进行处理。其中的部分源代码为:

p.add(new Label(“请选择你要的服务”));

this.add(p);

button1 = new Button(“存款”);

p1.add(button1);

this.add(p1);

button2 = new Button(“取款”);

p2.add(button2);

this.add(p2);

button3 = new Button(“查询余额”);

p3.add(button3);

this.add(p3);

button4 = new Button(“退出”);

p4.add(button4);

this.add(p4);

button5 = new Button(“修改密码”);

p5.add(button5);

this.add(p5);

this.addWindowListener(new WindowAdapter(){

public void windowClosing(WindowEvent e){

System.exit(0);

}

}

});button2.addActionListener(this);button3.addActionListener(this);button4.addActionListener(this);button5.addActionListener(this);setBounds(300,300,300,300);setVisible(true);validate();} public void actionPerformed(ActionEvent e){ if(e.getSource()==button2){//取款

dispose();

GetBalance gb = new GetBalance(“取款”,act);} if(e.getSource()==button3){//查询余额

Query q =new Query(“查询余额”,act);

dispose();} else if(e.getSource()==button4){//退出

dispose();

} JOptionPane.showMessageDialog(null, “谢谢使用!”, “消息!”,JOptionPane.INFORMATION_MESSAGE);System.exit(0);

} else if(e.getSource()==button5){//修改密码

ChangePassword cp = new ChangePassword(“修改密码”,act);

dispose();} 4.3.3 取款模块设计

在取款模块中,和其他的界面也是同样的结构。也是有一个文本框和一个按钮还有标签组成的。用户在文本框中输入他想取的数额,但是必须是100的倍数,而且每一次最多只能取5000块。当然了取款的时候也不能超过卡里的余额,再就是卡里的余额不可以为负,否则就会弹出报错的窗口。其方法为:

if(e.getSource()== button){

if(act.get_Money()< 0){// 判断余额是否为负

dispose();JOptionPane.showMessageDialog(null, “余额为负数”, “消息”,JOptionPane.INFORMATION_MESSAGE);} else if(money <= act.get_Money()){// 取钱的数额不大于余额

if(money % 100 == 0){

dispose();

JOptionPane.showMessageDialog(null, “取款成功!”, “消息”,JOptionPane.INFORMATION_MESSAGE);act.set_Balance(money);this.setVisible(false);Selection s = new Selection(“选择服务”, act);}

if((money % 100!= 0)||(money >= 5000)){// 取钱数为100的倍数或不大于5000

dispose();

JOptionPane.showMessageDialog(null,的钱!“, ”消息“,务窗口

}

”每次只能取100的倍数,而且不能超过5000,请重新输入你想取

JOptionPane.INFORMATION_MESSAGE);act.get_Money();this.setVisible(false);Selection s = new Selection(“选择服务”, act);// 返回选择服} else if(money > act.get_Money()){// 判断取款数额是否大于余额

dispose();

JOptionPane.showMessageDialog(null, “超过已有的钱数,请重新输入你想取的钱!”,“消息”, JOptionPane.INFORMATION_MESSAGE);

this.setVisible(false);

} Selection s = new Selection(“选择服务”, act);} 4.3.4 修改密码模块设计

在修改密码模块中,首先你必须要输入你的旧密码是否正确,否则就会报错。再一个就是要两次输入你的新密码,且两次药匹配,否则也会报错,然后再重新回到修改密码的界面。在修改密码时用到的方法为:

/*判断旧密码是是否正确*/ if(pwd2.equals(act.get_Password())){ /*判断两次输入的密码是否匹配*/

if(pwd3.equals(pwd4)){

/*如果都正确的话就设置新密码*/

act.setPassword(pwd3);

dispose();

Selection s = new Selection(“选择”,act);}else{

dispose();

ErrorWarn2 ew2 = new ErrorWarn2(“消息”,act);

} }else{

this.setVisible(false);

ErrorWarn3 ew1 = new ErrorWarn3(“消息”,act);

dispose();} 4.3.5 查询余额模块设计

在查询余额模块设计中, 和其他的界面的结构相差不多。有一个余额显示和一个按钮还有标签组成的。查询时用到的方法:

Query(String s, Account act){// 构造函数

super(s);this.act = act;button = new Button(“确定”);// TextField tf = new TextField(6);Panel panel1 = new Panel();Panel panel = new Panel();panel1.add(new Label(“你的余额为: ” + act.get_Money()));// 查询余额的button.addActionListener(this);panel.add(button);this.add(panel);this.add(panel1);this.setLayout(new GridLayout(2, 1));this.addWindowListener(new WindowAdapter(){ public void windowClosing(WindowEvent e){

System.exit(0);} });setBounds(300, 300, 300, 300);setVisible(true);

方法

} 4.3.6 退卡模块设计

在退卡模块设计中,这个方法就更加的简单了,它只是用了if(e.getSource()==button4){//退出

dispose();JOptionPane.showMessageDialog(null, “谢谢使用!”, “消息!”,JOptionPane.INFORMATION_MESSAGE);System.exit(0);} 这个方法就可以实现了,这里就不再多说了。

4.4 异常处理情况说明

(1)打开、保存文件时的异常处理 需要处理的异常:IOException(2)数据库访问时的异常处理 需要处理的异常:SQLException(3)加载类时的异常处理

需要处理的异常:ClassNotFindException,当应用程序试图使用Class类中的forName方法通过字符串名加载类时,但是没有找到具有指定名称的类的定义。

(4)加载URL时的异常

需要处理的异常:MalformedURLException,抛出这一异常指示出现了错误的 URL。或者在规范字符串中找不到任何合法协议,或者无法分析字符串。系统实现与测试

(1)编译运行程序后,将会看到如下的界面,如图2所示。如果输入的密码或卡号不正确的话就会报右下图的错误。

图2 主界面—登陆页面

(2)选择服务界面效果

当输入的密码和卡号正确,单击确定后就会进入到选择服务的界面,如图3所示。然后就可以选择所需要的服务了。

图3 选择服务界面

(3)取款界面,如图4所示。

图4 取款界面

当输入的钱数不是100的倍数或每一次大于5000时就会报图5的错误。

图5 输入错误1 当取款时如果超过卡里的余额的话就会报图6的错误。

图6 输入错误2(4)查询余额界面,如图7所示。

图7 查询余额界面

(5)修改密码界面,如图8所示。

图8 修改密码界面

当输入的初始密码不正确会报图9所示错误。

图9 输入错误1

当2次输入的新密码不同会报图10所示错误。

图10 输入错误2

经过测试,所有的功能基本上都实现了,而且运行正常。课程设计总结

6.1 遇到的问题及解决办法

在此次课程设计中遇到了一些问题,如:对于面向对象的方法了解不够透彻,运用到实际的软件开发中存在着困难;对于Java语言,只学习到了一些最基本的知识,这导致编写程序时经常出现一些语法错误,而且要在短时间内用Java语言来设计一个具体的系统是一个较大的挑战;还有对于正规开发一个系统的流程不熟悉,适应起来比较慢,编写各个模块相对应的操作时,自己感觉难以动手,这表明所学的知识不能灵活运用到实际中。

对于以上的问题,自己有清楚的认识,解决办法是需要大量阅读相关的书籍,对于书上以及网站上下载的资料中的Java实例必须有清楚的理解,还有就是多跟精通此方面的老师和同学交流,取其精华。对于实际动手能力与系统开发的流程的适应,必须多进

行实际的练习与操作,才能有大的进步。

6.2 心得体会

在这次的课程设计中,主要运用了Java语言的界面设计、异常处理、、Awt控件、Swing控件,输入输出流等,综合运用了Java语言。深刻感受到了面向对象语言中类库的强大功能,掌握了运用Java中的类实现某些基本功能,并学会了自己查询使用类的方法,为以后的面向对象语言的自学奠定了基础。

通过这次课程设计我学到了一些东西,这次的课程设计中,主要是运用JAVA语言来编写一个小的应用程序,当然还可以用其他的技术来辅助。在这个小应用程序当中,我用了Java外还用了Swing控件。输入输出流等。由于以前学的不是很扎实,而且还有些知识我们都是没有学过的,这就要求我们去查相关的书籍,还有就是和同学之间的交流。正因为这样,才锻炼了我的自学的能力,还有就是加深了我对各个知识点的认识,并且提高了我对专业的学习的兴趣,为我以后的学习打下了基础。此外,还感受到了面向对象语言的类库的强大的功能,掌握了运用JAVA中的类实现某些基本功能,并学会了自己查询使用类的方法,也就是要会用API文档,为以后更好的学习面向对象语言奠定了基础。

通过努力,这次课程设计终于完成了,在这个过程当中,学到了很多的知识,同时也感谢我的同学的帮助和指导。在以后的学习当中,我会更加努力的学习好专业知识,并将所学的知识用于实践当中去,以便牢固掌握知识。

参考文献

[1] 王萌,刘婧,来宾著.JAVA程序设计[M]北京 冶金工业出版社,2004 [2] 黄聪明 精通 JAVA2程序设计[M]北京:清华大学出版社,2004.4 [3] 王文涛,袁海燕 JAVA实用程序设计100例[M]北京:人民邮电出版社,2005.5 [4] 雍俊海 JAVA程序设计[M]北京:清华大学出版社,2006.8 [5] 刘宝林 JAVA程序设计与案例[M]北京:高等教育出版社,2006.11 附录(源码)

/******登陆页面首窗口*******/ import javax.swing.*;import java.awt.*;import javax.swing.border.*;import java.awt.event.*;

import java.io.*;

public class WindowBox extends Frame implements ActionListener { Box baseBox, box1, box2;TextField tf1, tf2;Button button1;Button button2;

WindowBox(String s){// 构造方法

super(s);tf1 = new TextField(6);tf2 = new TextField(6);box1 = Box.createVerticalBox();

box1.add(new Label(“请输入你的卡号”));// 输入卡号 box1.add(Box.createVerticalStrut(8));box1.add(new Label(“请输入你的密码”));// 输入密码 box2 = Box.createVerticalBox();box2.add(tf1);// box2.add(new TextField(16));

box2.add(Box.createVerticalStrut(8));box2.add(tf2);// box2.add(new TextField(16));

baseBox = Box.createHorizontalBox();baseBox.add(box1);baseBox.add(Box.createHorizontalStrut(10));baseBox.add(box2);add(baseBox);button1 = new Button(“确定”);// 加入按钮 button1.addActionListener(this);add(button1);button2 = new Button(“退卡”);// 退卡按钮 button2.addActionListener(this);add(button2);setLayout(new FlowLayout());/* 监听器 */

this.addWindowListener(new WindowAdapter(){ public void windowClosing(WindowEvent e){

System.exit(0);} });setBounds(300,300,220,220);setVisible(true);} public void actionPerformed(ActionEvent e){

Account act;String card;String pwd;act = new Account(“000000”, “Devil”, “123456”, 50000);// 初始化 /* 选择各种服务 */

if(e.getSource()== button1){

String number1, number2;// 输入的两个卡号和密码的变量 number1 = tf1.getText();number2 = tf2.getText();/* 判断两次输入的卡号和密码是否正确 */

if((act.get_Code().equals(number1))

&&(act.get_Password().equals(number2))){ dispose();Selection s = new Selection(“选择服务”, act);} else { dispose();

JOptionPane.showMessageDialog(null, “您输入的卡号或密码不正确,请核实后再确定”,“消息!”, JOptionPane.INFORMATION_MESSAGE);

// 报输入密码或卡号不正确

new WindowBox(“登录界面”);

}

}

if(e.getSource()== button2){

System.exit(0);

dispose();// 退出

} } }

/*************主函数****************/ public class ATM { public static void main(String[] args){

new WindowBox(“登录页面”);} } /********* 选择服务窗口 ***************/ import java.awt.*;import java.awt.event.*;

public class Selection extends Frame implements ActionListener { Button button1, button2, button3, button4, button5;

Panel p1 = new Panel();Panel p2 = new Panel();Panel p3 = new Panel();Panel p4 = new Panel();Panel p5 = new Panel();Panel p = new Panel();Account act;public Selection(){ } Selection(String s, Account act){ super(s);this.act = act;this.setLayout(null);this.setLayout(new GridLayout(6, 1));

p.add(new Label(“请选择你要的服务”));this.add(p);/* 各种服务功能 */

button1 = new Button(“存款”);p1.add(button1);this.add(p1);button2 = new Button(“取款”);p2.add(button2);this.add(p2);button3 = new Button(“查询余额”);p3.add(button3);this.add(p3);button4 = new Button(“退出”);p4.add(button4);this.add(p4);button5 = new Button(“修改密码”);p5.add(button5);this.add(p5);this.addWindowListener(new WindowAdapter(){ public void windowClosing(WindowEvent e){

System.exit(0);} });button2.addActionListener(this);button3.addActionListener(this);button4.addActionListener(this);button5.addActionListener(this);setBounds(300, 300, 300, 300);setVisible(true);validate();

} } public void actionPerformed(ActionEvent e){

} if(e.getSource()== button2){// 取款

dispose();GetBalance gb = new GetBalance(“取款”, act);} if(e.getSource()== button3){// 查询余额

Query q = new Query(“查询余额”, act);dispose();} else if(e.getSource()== button4){// 退出

dispose();

JOptionPane.showMessageDialog(null, “谢谢使用!”, “消息!”,JOptionPane.INFORMATION_MESSAGE);System.exit(0);} else if(e.getSource()== button5){// 修改密码

ChangePassword cp = new ChangePassword(“修改密码”, act);dispose();} /**********取款功能************/ import javax.swing.*;import java.awt.*;import javax.swing.border.*;import java.awt.event.*;

public class GetBalance extends Frame implements ActionListener { Box baseBox, box1, box2;Button button;TextField tf;Account act;

GetBalance(String s, Account act){// 构造函数

super(s);this.act = act;

button = new Button(“确定”);Panel panel = new Panel();Panel panel1 = new Panel();tf = new TextField(6);this.setLayout(new GridLayout(2, 1));panel1.add(new Label(“请输入你想取钱的数目”));panel1.add(tf);panel.add(button);this.add(panel1);

this.add(panel);button.addActionListener(this);this.addWindowListener(new WindowAdapter(){

public void windowClosing(WindowEvent e){

System.exit(0);

} });setBounds(300, 300, 300, 300);this.setVisible(true);} public void actionPerformed(ActionEvent e){ // System.out.println(e.getActionCommand());

double money;money = Double.parseDouble(tf.getText().trim());if(e.getSource()== button){

if(act.get_Money()< 0){// 判断余额是否为负

dispose();JOptionPane.showMessageDialog(null, “余额为负数”, “消息”,JOptionPane.INFORMATION_MESSAGE);} else if(money <= act.get_Money()){// 取钱的数额不大于余额

if(money % 100 == 0){

dispose();

JOptionPane.showMessageDialog(null, “取款成功!”, “消息”,JOptionPane.INFORMATION_MESSAGE);act.set_Balance(money);this.setVisible(false);Selection s = new Selection(“选择服务”, act);}

if((money % 100!= 0)||(money >= 5000)){// 取钱数为100的倍数或不大于5000

dispose();

JOptionPane.showMessageDialog(null,的钱!“, ”消息“,务窗口

”每次只能取100的倍数,而且不能超过5000,请重新输入你想取

JOptionPane.INFORMATION_MESSAGE);act.get_Money();this.setVisible(false);Selection s = new Selection(“选择服务”, act);// 返回选择服 // dispose();} } else if(money > act.get_Money()){// 判断取款数额是否大于余额

dispose();JOptionPane.showMessageDialog(null, “超过已有的钱数,请重新输入

你想取的钱!”,“消息”, JOptionPane.INFORMATION_MESSAGE);

this.setVisible(false);口

Selection s = new Selection(“选择服务”, act);// 返回选择服务窗

} } } }

/********修改密码功能*************/ import java.awt.Button;import java.awt.Frame;import java.awt.GridLayout;import java.awt.Label;import java.awt.Panel;import java.awt.TextField;import java.awt.event.ActionEvent;import java.awt.event.ActionListener;import java.awt.event.WindowAdapter;import java.awt.event.WindowEvent;import javax.swing.JOptionPane;

public class ChangePassword extends Frame implements ActionListener { Panel panel1 = new Panel();Panel panel2 = new Panel();Panel panel3 = new Panel();Panel panel = new Panel();TextField tf4, tf5, tf6;Button button;Account act;ChangePassword(String s, Account act){

super(s);

this.act = act;

tf4 = new TextField(6);

tf5 = new TextField(6);

tf6 = new TextField(6);

button = new Button(“确定”);button.addActionListener(this);/* 建立新密码 */

panel1.add(new Label(“请输入你的旧密码:”));panel1.add(tf4);panel2.add(new Label(“请输入你的新密码:”));panel2.add(tf5);

} panel3.add(new Label(“请再次输入你的新密码”));panel3.add(tf6);panel.add(button);this.add(panel1);this.add(panel2);this.add(panel3);this.add(panel);setLayout(new GridLayout(4, 1));setBounds(300, 300, 300, 300);this.setVisible(true);/* 窗口事件 */

this.addWindowListener(new WindowAdapter(){ public void windowClosing(WindowEvent e){

System.exit(0);} });/* 判断事件源,看条件是否成立再修改密码 */

public void actionPerformed(ActionEvent e){ if(e.getSource()== button){

String pwd2, pwd3, pwd4;

pwd2 = tf4.getText();

pwd3 = tf5.getText();

pwd4 = tf6.getText();

if(pwd2.equals(act.get_Password())){// 判断旧密码是否正确

if(pwd3.equals(pwd4)){// 判断两次输入的新密码是个匹配

act.setPassword(pwd3);// 启用新的密码

dispose();

JOptionPane.showMessageDialog(null, “密码修改成功!”, “消息

JOptionPane.INFORMATION_MESSAGE);

”,Selection s = new Selection(“选择”, act);// 返回服务窗口 } else { this.setVisible(true);

// ErrorWarn2 ew = new ErrorWarn2(“消息”,act);dispose();JOptionPane.showMessageDialog(null, “两次密码输入不匹配”, “

JOptionPane.INFORMATION_MESSAGE);

消息”,Selection s = new Selection(“选择”, act);// 返回服务窗口

} } else { this.setVisible(false);dispose();

“,} JOptionPane.showMessageDialog(null, ”初始密码输入错误“, ”消息

JOptionPane.INFORMATION_MESSAGE);

Selection s = new Selection(“选择”, act);// 返回选择服务窗口

} } } /**************查询余额功能******************/ import javax.swing.*;import java.awt.*;import javax.swing.border.*;import java.awt.event.*;

public class Query extends Frame implements ActionListener { Button button;Account act;

Query(String s, Account act){// 构造函数

super(s);this.act = act;

button = new Button(“确定”);// TextField tf = new TextField(6);Panel panel1 = new Panel();Panel panel = new Panel();

panel1.add(new Label(“你的余额为: ” + act.get_Money()));// 查询余额的方法

// panel1.add(tf);

button.addActionListener(this);

panel.add(button);

this.add(panel);

this.add(panel1);

this.setLayout(new GridLayout(2, 1));

this.addWindowListener(new WindowAdapter(){

public void windowClosing(WindowEvent e){

System.exit(0);

}

});

setBounds(300, 300, 300, 300);

setVisible(true);} public void actionPerformed(ActionEvent e){

if(e.getSource()== button){

dispose();

Selection s = new Selection(“选择服务”, act);// 返回选择服务窗口

} } }

/***********账户****************/ import java.io.*;/* 该类为实现客户信息及部分功能 */ public class Account {

{

} private String code = null;// 信用卡号 private String name = null;// 客户姓名

private String password = null;// 客户密码 private double money = 0.0;// 卡里金额

public Account(String code, String name, String password, double money)

} this.code = code;this.name = name;this.password = password;this.money = money;public String get_Code(){// 取得卡号

return code;} public String get_Name(){// 取得名字

return name;} public String get_Password(){// 取得密码

return password;} public double get_Money(){// 重置余额

return money;} /* 得到剩余的钱的数目 */

protected void set_Balance(double mon){ money-= mon;} /* 重置密码的方法 */

快速搭建虚拟机 第3篇

设置VirtualBox

使用VirtualBox可以非常轻松地建立虚拟机并安装操作系统,但仍有一些VirtualBox的设置选项是我们需要考虑的。首先,默认设置下,虚拟机软件将所有的数据存储在同一个文件夹中,由于虚拟机磁盘文件大小通常动辄10GB以上,大部分用户的磁盘未必有足够的剩余空间,因而必要时可以选择VirtualBox主界面中的“管理|全局设置”,在“VirtualBox - 设置”对话框“常规”设置选项中点击“默认虚拟电脑位置”下拉菜单,选择“其他”来修改默认的数据存储路径。其次,在建立虚拟机的过程中,VirtualBox将允许用户自行决定使用的虚拟磁盘格式,我们建议使用“VHD”格式,该格式使用更广泛,能够被很多系统和软件所支持。

注意事项

在为虚拟机安装系统的过程中,必须特别小心地选择系统的安装磁盘,错误地选择当前系统的磁盘进行安装,将可能导致当前系统无法正常使用。其次,在虚拟机上安装的操作系统同样需要一个单独的版权许可,因此,同样需要考虑系统激活等相关的问题。

另外,VirtualBox菜单中包含许多设备相关的功能,使用它们的时候需要考虑是否影响当前系统的运行。例如,通过“设备|分配USB设备”我们可以将一个USB设备挂载到虚拟机中,但与此同时该设备将从主机中卸载,这将可能导致丢失当前系统尚未保存的数据,因而,必须确保主机已经保存数据之后,再进行类似的操作。

步骤

安装VitualBox 简单地点击几下即可完成VitualBox的安装,接下来安装程序将逐一要求用户同意安装USB控制器与网络适配器等驱动程序。

安装扩展包 在软件主界面上单击“管理|全局设置”,选择“Extension”并单击右侧上方按钮“Add package”,选择下载的扩展包进行安装。

建立虚拟机 单击“控制|新建”,然后选择“下一步”,键入自定义的虚拟机名称,并从下方的下拉菜单中选择准备安装的操作系统版本。

设置虚拟机 接下来,我们需要为虚拟机分配内存并创建虚拟磁盘,对于“VHD”等常见的虚拟磁盘文件,VitualBox支持直接导入使用。

安装操作系统 软件支持直接通过虚拟光盘驱动器加载安装光盘镜像进行操作系统的安装。

配置设备 在虚拟机界面上单击“设备|分配USB设备”可以将特定的设备挂载到虚拟机中,例如一个准备在虚拟机系统中使用的打印机。

安装驱动程序 设备挂载到虚拟机之后,虚拟机系统将需要启动驱动器程序安装向导为其安装驱动程序,接下来我们就可以在虚拟机中使用该设备了。

Java虚拟机的系统优化研究 第4篇

关键词:Java,虚拟机,系统优化

1 Java虚拟机的定义和发展现状

1.1 Java虚拟机定义

Java虚拟机,缩写为JVM是一个虚构出来的计算机,实际的运行主要是通过在实际的计算机上仿真模拟各种计算机功能来实现,具有自己完善的硬件架构以及相应的指令系统。其实,虚拟机并不是Java语言本身,它是个为特定及其编写的解释性软件。Java的虚拟机就相当于世界通用语言,能够被所有的设备同时应用,这是个人类创造的目的就是使得不同语言之间的翻译沟通更加容易。目前在金融、交通运输、电子商务、无线通讯等行业具有前瞻性和适用性发展,与此同时网络交易更加快捷与安全,使得Java成为目前网络上流行的编程语言。

1.2 发展现状

Java虚拟机是Java语言的灵魂,是Java技术的核心关键之处,尤其适合于分布式计算环境或面积相对较小的智能嵌入式系统。Java开发是由Sun Microsystems公司在1995年设计并推出的,主要包括Java程序设计语言和Java平台等方面。Java语言发展至今,Java扩展管理规范面向Java平台为其真正运行与网络管理模式的选择提供了一种新型的、规范的管理框架;Java扩展管理规范还带来了一系列标准统一的代理及服务。就目前而言,无论哪个Java应用程序设计和开发的人员都完全可以使用这些代理及服务用来监测Java虚拟机的运行状况。Java扩展管理规范具备跨越异构的系统体系结构、异构的操作系统平台以及异构的网络传输协议对分布式系统管理问题有着自己独特的解决办法可以在不同的环境下使用,使得Java虚拟机的性能监测变得简单。

2 Java虚拟机特点

2.1 广泛的跨平台性

一般的高级编程语言,需要编译成不同的目标代码以满足在其他平台不同界面上能够成功运行。而Java语言具有独特的可移植性,正是通过Java虚拟机避免了特定平台的干扰,直接处理Java源代码编译成的字节码与平台无关,保障“编译一次,自由执行”的特性,因此只要在目标机器上实现了符合规范的运行程序环境,就可以运行所有的Java程序。

2.2 强健的安全性

因为Java不支持指针等对安全机制存在影响的程序,但鼓励垃圾回收机制以及代码安全性检测,可以随时申请、自动释放内存资源避免因为内存耗尽而死机并且在一切对内存进行的访问都必须经过对象变量来实现,在程序正常运行之前必须进行安全检查、未经授权禁止读写文件并采用隔离的方法限制非法入侵的范围。

2.3 灵活的动态性

Java语言程序为保证数据的安全和出于简单性原则本身是不允许多重继承,但是可以通过接口来支持多重继承,与其他严格的类继承相比较具有更高的自由性和扩展性。还可以根据用户的需要,实现动态添加和删除信息,下载重要资源,扩大软件配置、维护、更新的范围而不会影响用户原有程序的执行,操作简便易行,受到更多青睐,为日益普及的网络应用提供了良好的基础。

3 Java虚拟机运行时执行的性能较低

通过资料查询,可以发现Java语言程序更适合于计算机互联网络的开发应用,其中关键的一点原因就是运行的过程中使用了虚拟机,虚拟机的实质是一个用来解释Java系统指令的软件包。保证了Java语言程序在任何机器下运行成为可能。JVM的性能体现在工作站和服务器上已经得到了很大提高,但是使用虚拟机而带来增加的额外抽象造成应用在虚拟机上的执行要比在本地平台执行的速度更慢,有时性能达不到要求。

由于常见的服务器和PC工作站大多是拥有64位或以上宽度的内存总线以及高主频CPU,所以一些短暂的停滞显得微不足道,可以简单地忽略不计。但如果碰到比较低端的移动通信设备和智能终端,就极容易发生让程序的启动速度变得很慢、启动时间延长的现象,还有一定几率产生较为明显地在指令完成过程中出现停顿和反应迟钝。提升程序性能的途径有很多,对于Java语言的相关程序性能的进一步提升应该采取遵循它的跨平台性和安全性的前提之下,而Java虚拟机的存在就是保障Java程序跨平台性和安全性的基础性要求,因此应该采用多种编译优化技术提高虚拟机的运行能力。

4 优化虚拟机性能的常用方法

4.1 采用FPGA硬件支持

如何借助硬件方式来解决Java虚拟机性能缺陷一直是厂商长久以来研究的关注点。尤其是随着信息化发展FPGA性能的日益提高,为Java虚拟机开发与设计提供更高的硬件支持成为可能。

编程逻辑器件的相对优势:第一,我们可以清晰认识到硬件设备专向专项设计变通、储蓄运载功能强大等方向发展,其中最突出的是高密度的FPGA硬件设备,其无论从运行速度、功能消耗和销售价格在内的很多特点已经能够充分与ASIC器件相比较。FPGA硬件的可重构计算特点极大地缩小了ASIC器件同传统软件之间的距离;第二,由于可配置硬件器件的存在,为用户提供了多重选择,综合利用软件工具设计硬件从而达到快速原型生成的目的,缩短产品生产周期、产品上市时间提早,取得先发制人的优势;第三,自由灵活的可配置性也可以确保可重构计算能够在计算开始的初期,甚至在程序运行的过程中实现现场配置,一些研究性的工作通过为Java虚拟机设计提供FPGA硬件在性能上收获很大。

4.2 即时编译的手段

基于现行的动态编译的执行模式,本文对Java程序性能的优化方面主要集中体现在基于即时编译技术的运行过程中优化。多项数据显示,基于字节码的优化空间非常有限,以完整保留Java字节码的跨平台的特性为目的,性能优化加速率仅仅为1%—3%;同时,Java语言程序特有的一些动态语言特性,如动态类加载,也要求众多的基于Java程序的优化只能被推迟到运行时进行。因此,对于Java程序的性能优化更多的依赖即时编译技术。即时编译技术即是Just-In-Time,简称JIT。可以笼统认为是在运行JAVA程序时,任何程序语言的执行通过翻译成为本地的机器指令是唯一途径,而Java虚拟机会根据字节码进行翻译,整个编译过程一般在字节码运行的前面发生。实际上,最初采用JIT技术的JVM进行即时编译的时候利用一个通用接口来调用外部代码翻译单元,代码翻译单元并不包括在JVM程序里面。JIT方法的结构图如图1所示:

即时编译的最小单位就是Java方法。在运行一个Java方法之前,Java虚拟机就会把这方法的一些有关信息提供给JIT单元,同时直接运行编译后的本地代码。以后调用这种方法检测后都会对编译后的本地代码直接运行,其运行过程不受时间和次数的限制。

由于JVM与JIT单元摆脱了对Java的单一继承性,凭借开放式JIT接口的使用而促使相对独立,使得任何第三方开发人员都可以自由的进入系统实现编写JIT单元,无需受到来自JVM程序内部的其他要求的制约和干扰。Java程序的典型性运行方式主要是依靠目标终端的JVM用来执行Java的字节码文件。首先,解释器的翻译和执行性能相对较差,基本上除了嵌入式系统之外,大多数目标平台的JVM均会使用JIT对载入成功后的字节码统一进行优化编译并且执行。验证模块是用于对载入的字节码进行准确性检验,包括类型检查和字节码文件结构等。由于JIT技术的出现,对了Java程序的性能进行了显著地提高,几乎改变了过去人们对Java程序性能差的印象。

5 结论

基于Java语言程序的特点出发,保证强健的安全性是Java语言设计的最基本也是最重要的要求之一,虽然厂商和领域内针对Java平台的安全性从许多方面进行了富有专业性考虑,但是这些解决方案或多或少都存在不完善之处。主要是因为存储字节码的类文件的格式公开,又由于Java语言还要兼顾跨平台性以及可移植性,字节码的指令系统中一定会表现出相应的Java源代码中较多的信息,字节码的格式也比较固定,自然也就为反编译Java字节码文件来得到Java源代码提供了可能性。本文找到了现有Java虚拟机运行硬件性能不足的问题进行分析,确定采用方法内嵌、FPGA硬件支持、即时编译等手段对性能局限进行理解优化。对此完整地设计并实现了一套适于Java开发运行环境优化解决方案,为防止低水平重复开发、加快国产软件商品化、产业化的优先办法。

参考文献

[1]贺蕴彬.Java虚拟机的自适应动态优化[J].科技创新与应用,2014(5).

[2]尹相志,胡百敬.SQL Server 2008 R2 Reporting Services报表服务[M].北京:中国水利水电出版社,2012.

不用安装 急速打造虚拟机系统 第5篇

如果我们想在Win 7下快速安装虚拟的WinXP系统,可以使用Ghost和VHD这两大技术帮忙。原理很简单,Win7和虚拟机都支持VHD磁盘文件的加载和管理,那么我们先建立一个空的VHD磁盘,然后用Ghost还原的功能将系统丢到VHD磁盘中,再让虚拟机(这里以“Microsoft Virtual PC 2007”为例,下载地址:http://tinyurl.com/7hs4ly6)直接加载它就好了。

准备好“winxp.gho”文件和用于还原的“Ghost32.exe”程序,“winxp.gho”可以在各种Ghost XP系统光盘中找到。其名字可能不是“winxp”,但只要格式为GHO,大小约600MB大小的文件就是它了。

右键点击桌面的“计算机”选择“管理”,在打开的管理窗口中展开“计算机管理(本地)→存储→磁盘管理”选项。再右击“磁盘管理”选择“创建”,按提示在任意NTFS分区(假设为J盘)中创建一个名为“winxp.vhd”、类型为“动态扩展”、大小为10GB的VHD文件(如图1)。

VHD文件创建完成后,按后续提示完成VHD磁盘分区的初始化,并将其创建为主分区。创建完成后右键点击VHD磁盘,选择“将分区标记为为活动分区”(如图3),这样一个可用于虚拟机启动的VHD空磁盘就建立好了。

运行“Ghost32.exe”程序,选择“Partition→From Image”,弹出选择框,先是选择“Image”文件,定位到“winxp.gho”文件上即可,然后选择被还原的磁盘分区,点中名为“Msft Vitrual Disk1.0”(即VHD磁盘,如图4)的磁盘主分区,点击“OK”进行还原。

因为所有操作都在一块硬盘中,所以这还原速度飞快。普通情况下,一个WinXP还原也就是3分钟不到。还原完毕,虚拟WinXP的安装就完成了一大半。返回“计算机管理窗口”,右键选择VHD分区,选择“分离VHD”(如图5)。

接下来就是用虚拟机加载这个分离出的VHD文件了。运行“Microsoft Virtual PC 2007”,按向导提示创建虚拟机,在“虚拟硬盘选项”这一步,选择“一个已存在的虚拟硬盘”(如图6),然后导入之前制作的“winxp.vhd”文件。

创建完毕后就可以用虚拟机加载它并运行了,其具体效果与用Ghost XP光盘在实体机上刚装完是一样的。对于熟练者来说,该虚拟系统的安装不会超过10分钟,如果是常规安装可能还在慢慢地复制文件……

巧借软件,WinXP虚拟Win7迅如雷

在WinXP 下安装Win7虚拟系统的原理其实都一样,只是WinXP不支持VHD文件的创建和加载,我们需要借助第三方软件。

这里我们需要能创建和加载VHD文件的“WinXP_VHD辅助处理工具”,然后还要能合并Win7文件到VHD分区的“gimagex”程序,最后为了保证虚拟机系统的启动,还需要能修改VHD分区里面启动项的“bootice”程序(这些程序在http:// work.newhua.com/pcd中能找到)。当然,Win7的安装盘文件也需要准备好。

运行“WinXP_VHD辅助处理工具”,单击“创建V H D”。在创建的设置中,“VHD的位置”选择“J:win7.vhd”(J盘可以是任何空间足够的NTFS分区),VHD大小和格式使用默认设置。在“装入VHD的GhostXP的位置”处,把Win7的光盘文件路径添加进去,点击“确定”(如图7)。

此时程序会自动创建VHD磁盘并加载到系统中,等到屏幕出现“成功指派驱动器号或装载点”提示时,则表明VHD创建加载成功(如图8)。

然后程序会开启Ghost程序进行还原,当然这里是不会成功的。屏幕会马上提示操作失败,请不要关闭该窗口(如图9,否则VHD磁盘会自动卸载,无法继续),继续后续的操作。

打开“我的电脑”,会看到新增一个Z盘,这是程序自动创建的VHD磁盘,右键点击它在弹出菜单中选择“格式化”,按提示将其格式化为NTFS分区。

将Win7安装盘文件解压到额外的分区中(这里是N盘),启动“gimagex.exe”程序,切换到“应用映像”标签。在“选择映像”处选择刚才解压出来的“N:sourcesinstall.wim”文件,“应用到”的盘符选择刚新增的Z盘,“选择应用的映像”选择5,最后单击“应用”(如图10)。这样就能把Win7的内容复制到Z盘,也就是创建的VHD磁盘中去。

此时的VHD磁盘已经有Win7系统了,不过还不能实现自我启动。将N盘被解压出来的“bootmgr”文件和“boot”目录复制到Z盘中,接着启动“bootice.exe”,在目标磁盘选中“MSFT Vitrual Disk”(即加载的VHD磁盘),单击“主引导记录”(如图11)。

在打开的新窗口中,勾选“windows NT6.x默认引导程序”复选框,然后单击“安装/配置”更改VHD磁盘引导记录为NT60格式。

返回bootice主界面,单击“分区管理”,在打开的窗口中选中主分区,单击“激活”按提示将虚拟磁盘分区设置为“活动主分区”。再次返回主界面,切换到“BCD编辑”标签,单选“其他位置BCD”,选择“N:bootbcd”文件,然后单击“查看/修改”。接着在弹出的编辑窗口单击“添加→Windows 7/vista/2008启动项”,将“启动磁盘”项选为当前VHD磁盘,然后“启动分区”项改成VHD磁盘分区,“菜单标题”写为“Windows 7”,其他设置保持默认状态(如图12)。最后依次单击“保存当前系统设置”和“保存全局设置”退出。

Java虚拟机的自适应动态优化 第6篇

Java虚拟机 (Java virtual machine) 作为一种具有抽象意义的计算机系统, 可以在具体的计算机上对多种计算机功能进行仿真模拟, 以此来实现特定的需求。Java Virtual Machine具有中央处理器、寄存器以及堆栈等一套完备的硬件体系, 也具备成熟的指令系统。为了实现Java程序可以在多种平台上不需要修改就可以运行, 可以依托Java virtual machine, 通过Java程序生成相应代码来运行即可。

2 Java虚拟机的特点

通常, Java语言与其所运行的平台无关, 这是Java语言的一个重要特点。其关键在于应用了ava virtual machine。使用其他高级语言编写的程序, 如果需要运行在不同的平台, 则要编译为多种不同的目标程序。而借助ava virtual machine, java语言不需要重新编辑即可在不同平台上运行。Java virtual machine执行目标代码时, 把目标代码解读为特定平台上的机器指令来遵循。

3 Java虚拟机的体系结构

Java virtual machine可以通过不同厂商来实现, 则因厂商的不同而造成Java virtual machine实现上的不同, 但这不影响Java virtual machine的跨平台特性, 这是因为Java virtual machine独特的体系结构。

Java virtual machine内部的抽象的体系结构由存储器、指令、数据类型和子系统组成。这些都提供了一种方式, 可以对外部行为进行定义。Java virtual machine的机制有两种, 类装载系统用于装载合适的类, 运行引擎用来执行已经装载的类的指令。每个Java virtual machine由堆、方法区、程序计数器、Java栈以及被你的方法栈, 同时, 搭配了运行引擎和类装载共同构成了Java virtual machine的体系结构 (如下图所示) 。

4 Java虚拟机的自适应动态优化

Java virtual machine类似于抽象意义上的堆栈计算机, 其作用是装载类文件, 然后运行其目标代码, 目标代码的操作次数都源于堆栈。现在, 常见的处理器都采用寄存器结构, 所以, Java virtual machine要对这些针对堆栈的命令通过即时编辑机或解释机进行解释, 解读为寄存器可以执行的指令。在解释和执行的次序上是解释一次执行一次, 并不包括解释后的机器指令。如果需要多次执行目标程序, 就要多次解释执行。但即时编译机会把首次执行的程序翻译为本地程序, 并在内存中缓存代码, 后续可以再次调用而实现该方法的复用。

Java virtual machine可以动态自适应去装载, 这种动态自适应装载类的模式促进了Java的灵活的网络性质。Java virtual machine既能装载本地的类程序, 也可以对网络上的类进行装载。Java virtual machine为了安全地管理这些不同装载器装载的类, 对其拟定了不同的名字, 以此, Java virtual machine能够依照名字把代码列入不同的类型, 然后对不同类型的代码执行不同的操作。

作为Java virtual machine的重要优化方法的内联, 难以实现面向对象的动态编程语言。所以, 基于Java的程序可以在运行的同时改变不同的调用模式, 也可以动态装载不同的Java程序以应对不同的需求。

面向全局进行分析的内联, 因为动态的装载而增加了复杂性。程序的全局关系被其改变, 则新加载的类程序就需要被内联。因此, Java virtual machine要动态的优化之前优化过的程序, 或者在执行热点代码的同时, 进行这种动态优化。否则, 一般的内联优化就不能系统地进行执行。

5 Java虚拟机的自适应的动态优化框架

Trace缓冲区、插桩器和动态优化策略挑选机共同构成了Java虚拟机的自适应动态优化框架。在即时编译机中, 插桩器执行对访问对象的指令开展插桩, 来获取Java对访问对象的相关信息。程序运行中的对象信息存放在Trace缓冲区里。动态优化策略挑选机参展缓冲区里的信息动态选择对Java程序的自适应优化策略。

上图描述了Trace缓冲区的构成。这是48KB的缓冲区, 其中的每一个单元是12字节。缓冲区的写入是自上而下。缓冲区的顶部和底部分别用不同的名称代表 (如图所示) 。缓冲区再向下部分不可写。应用程序把数据写入缓冲区, 溢出后, 就产生错误代码。即时编辑机编译Java目标代码, 把与平台无关的代码翻译为与平台相关的机器指令。编译器会在编译时识别该模式中的指令, 并对应开始插桩, 同时手机访问对象的情况。编辑后, Java程序在运行的过程中把访问对象的信息灌输到缓冲区里, 写满缓冲区后, 程序提醒, Java virtual machine获取提醒, 然后通知动态优化策略挑选器来执行优化。优化后, Java程序返回起始点再执行。

参考文献

[1]李锡祚, 霍华, 胡冠.嵌入式Java虚拟机优化研究[J].计算机应用与软件, 2009, 26 (7) :257-259.

[2]邓洋春.Java虚拟机关键机制研究与实践[D].中南大学, 2009.

[3]吴志军, 何加铭, 曾兴斌, 等.基于嵌入式Java虚拟机的垃圾收集优化算法[J].计算机工程, 2012, 38 (7) :46-48.

[4]陈灏, 陈榕.支持复合对象的Java虚拟机内存管理技术研究[J].电脑知识与技术, 2011, 7 (22) :5356-5359.

Java虚拟机 第7篇

自2010年国内运营商开始逐渐使用搭载Java虚拟机的智能卡产品至今已超过5年之久, 累计产品发行量过亿张。同时, 伴随近年来移动支付的蓬勃发展, 越来越多的Java卡应用如雨后春笋般出现并应用在Java智能卡中, 使重多用户享受到Java智能卡及应用的便利, 那么这些Java应用是如何在Java智能卡上运行的?以及如何提升Java卡核心——Java卡虚拟机的执行能效, 将是本文向大家阐述的重点内容。

二、Java卡及Java卡应用

2.1为什么要使用Java卡?

ORACLE公司的Java编程语言已逐渐成为除Microsoft公司的c语言体系之外, 另一种主流的商业软件开发语言。其崛起与发展如此迅猛, 既有Java作为开发语言本身所具备的诸多优势, 也与Java体系开发成本低、易于部署等诸多特点息息相关。Java语言诉求实现“应用与平台无关系性”——将上层应用与底层平台 (操作系统及硬件) 剥离开, 以实现“一次编写, 任意运行 (write once, run anywhere) ”的愿景, 为了达到这一目标, ORACLE公司提出了Java虚拟机的概念, 并将其应用于多个系统平台, 取得了巨大成功。

Java语言这种应用只需经过一次编译, 就可在任意软硬件平台中运行的特质, 十分符合现今电信智能卡应用的开发需求。众所周知, 传统的电信智能卡应用多为电信增值业务, 数量少, 功能简单, 由智能卡制造商根据自身产品的硬件及卡片操作系统 (COS) 以Native的形式开发实现。而由于各厂家的应用互不兼容, 无法交互使用, 因此一个应用需要所有卡片制造商都进行开发, 消耗巨大的开发、调试及维护成本。而随着移动支付领域的迅猛发展, 电信智能卡上需承载越来越多的第三方应用, 这些应用需求多样, 功能复杂, 且多是由第三方 (如银行等金融机构) 开发, 无法继续沿用传统电信智能卡应用的native开发模式, 于是Java卡的出现完美的解决了这个问题。

2.2 Java Applet是如何在Java虚拟机上运行的?

基于Java卡环境下的应用开发模式与其他高级语言平台开发模式基本类似——应用的开发方只需考虑如何使应用更好的实现功能, 带给用户更佳的使用体验, 而不必关心应用将装载在哪个平台, 该如何兼顾平台的特性。这些问题统统交由Java卡虚拟机来解决。因此在这种模式下, 应用开发商只需要开发一版Java卡应用 (以下称为Java Applet) , 就可以装载并运行在任意一张搭载了Java卡虚拟机的智能卡中。

每一个Java Applet从编写到最终在卡片中运行, 需要经过以下几个步骤:

1.开发者通过特有的开发环境, 使用Java语言编写源代码 (.Java文件) ,

2.将Java源码编译成字节码 (.class文件) 。字节码是是一种Java体系特有的代码形式, 它具有一定的可读性, 并可被Java虚拟机解析并执行。

3.编译好的字节码需要与对应的exp文件配合, 通过转换器转换为cap文件,

4.通过读卡器或者空中通道, 下载到Java卡上, 安装、实例化后才可正常使用。

5.当这个应用被选择执行时, 卡片的Java运行时找到该应用的虚拟机机器码对应的存储位置, 并将其载入Java虚拟机进行解析、执行。

在这整套复杂的过程中, 有以下两个最重要的环境:

A.class文件被转换成.cap文件的过程

该过程主要是将class文件的字节码转换成可被Java卡虚拟机识别并执行的虚拟机代码。由于ORACLE公司在JCVM规范中明确规定了Java虚拟机所支持的所有指令集, 因此这是一个标准的转换过程。

B.cap文件下载到卡片中的过程

该过程主要是卡商自身实现的Java运行时对cap的解析和转译过程, 由于ORACLE公司仅在相关规范中只规定cap文件的内容, 但未规定其在卡片内部的存储结构和格式, 因此这是一个非标的处理过程, 各智能卡制造商根据自身的Java卡设计情况将cap文件进行解析, 并按各自Java卡实现所设计的数据结构, 拆解、组合成私有格式, 存储在卡上。

三、Java卡运算能效因素及优化方向

3.1影响Java卡运算能效的因素

Java卡是相对比较复杂的电信智能卡产品, 其具备较强大的扩展性和灵活的移植性。它在传统的电信智能卡软、硬件环境基础上, 增加一层Java卡虚拟机和Java运行环境, 所有的Java应用需要加载到这套Java卡运行环境中才能正常运行。因此其运算性能受制于整套智能卡软、硬件条件。具体影响Java卡的运算能效的因素包括以下几点:

硬件层面:

CPU位数及主频

RAM容量

ulash读写速度

安全算法协处理器支持情况

软件层面:

Java虚拟机性能

Applet源码性能

3.2探寻Java卡性能优化的方向

一张Java卡产品的运算能效受其软、硬件环境的共同影响, 理论上, 更换更强大的卡片硬件环境, 如更快cpu, 更大的RAM空间或读写更快的Flash存储器等, 都可从根本上提升该Java卡的运算能效。同时, 对Java apple源代码的编写方式进行优化, 使用更科学的算法设计方法, 优化代码执行流程, 更有规律性、计划性的执行高耗时操作等, 也可直接提升该应用的执行效率。

但从市场化的角度考虑, 智能卡制造商对产品的硬件选型需要考虑成本和利润, 在一定时期内, 其使用在Java卡产品平台上的电信智能卡芯片硬件性能是固定的。而另一方面, Java卡相较传统native电信智能卡, 其设计初衷就是提高产品的开放性和开发效率, 将卡片实体生产者和卡片应用开发者分离, 因此在Java卡环境下Applet的开发必然是离散形式, 开发方并不可控, 因此从Applet的编写角度提出优化要求并不可行。因此, Java卡产品性能可行、有效且可控的优化方向, 应该是从电信智能卡制造商的Java虚拟机执行效能优化提升方向入手。

四、Java卡虚拟机的优化分析

4.1 Java虚拟机执行Applet原理解析

研究如何优化Java卡虚拟机的执行效率, 就需要弄清Java卡虚拟机是如何解析执行Java Applet的。我们以下面这个简单的“Hello World”应用作为示例, 解析Java虚拟机如何执行这个Applet的, 以下是“Hello World”应用的源代码:

这是一个最简单的Java应用, 主要实现的作用是:当该应用被选择执行后, 应用向卡外设备返回“Hello World”字符串。

这个Applet的源码被编译并转换后生成了该应用的cap文件, cap文件是一种压缩格式文件, 对其解压缩后, 可以看到它是由以下12个组件 (component) 组成:

每个组件都是一个表单格式的数据结构, 各自描述了这个Java应用的某方面信息, 我们可以通过读卡器或空中下载通道, 将这个cap下载到卡片中, 并安装执行。

下载到Java卡后, 当该Applet被执行时, Java虚拟机会执行以下操作:

对这些字节码进行解析可以发现, 在执行这个process函数时, 大致的过程主要是通过getstatic_a获取数据, 并通过astore_2、aload_2、sconst_5等堆栈操作函数将数据放入堆栈, 在通过invokestatic函数的调用相应的方法对堆栈中的数据进行运算, 最后通过pop将结果弹栈输出结果,

对于堆栈的操作, 由于缓存数据在芯片的RAM中操作, RAM的读写速度远远大于Flash存储域, 因此上述操作中涉及堆栈操作的执行速度会很快, 对Java卡虚拟机执行效率的影响也微乎其微。

而对于获取数据和调用方法的操作, 则需要根据其指令后面的参数进一步执行相关操纵, 例如getstatic_a类和invokestatic类指令:

7B (getstatic_a函数) 00 06 (参数)

8D (invokestatic函数) 00 07 (参数)

这两个指令的参数实际标示了该信息在Constant Pool (以下简称CP) Component中的位置。CP中主要存储了整个Applet中所有类、方法和域的入口信息。对”Hello World”应用的CP内容进行解析如下:

其中每条cp_info是一个常量成员的内容信息, 其结构如下:

由于Get类和invoke类指令的参数的结构不同, 因此这两种函数在CP中获取进一步常量信息的流程也不相同, 下面从”Hello World”应用的process函数中分别挑选一个Get类和一个invoke类函数, 阐述一下各自的执行流程:

4.1.1 getstatic_a指令

7B 00 06 getstatic_a

00 06表现需要获取的静态数据在cp中的位置为“0006”, 由于cp中成员index从0000开始, 因此此处表示需要获取cp_info7的内容“05 00 00 00”。其中“05”表示这是一个“CONSTANT_Static Fieldref”, 即后续的内容在Static Field Component中, 其后面第一个”00”表示这是一个内部地址, 后二个“00”表示其在Static Field Component中的index。对”Hello World”应用的Static Field Component内容进行解析如下:

这里根据cp中的入口地址找到, 需要调用的常量内容“80 48 65 6C 6C 6F 57 6F 72 6C 64 53 05”, 即”Hello World”这段字符Unicode码的数值。

至此可以看到, 根据method component中解析出需执行的虚拟机指令getstatic_a及其参数 (7B 00 06) , 最终找到了需要获取的常量数据。

4.1.2 invokestatic指令

8D 00 07 (invokestatic)

00 07表示需要获取的静态数据在cp中的位置为“0007”, 即cp_info8的内容“06 80 10 02”, 其中“06”表示这是一个“CONSTANT_Static Methodref”, “80”表示这个是一个外部的方法, 且包的id是“00”, “10”表示这个方法是引用的class_token, 而最后的“02”是这个方法的token。连贯起来理解, 就这此处需要调用的方法是token为00的package下token为10的class中的“02”方法。

由于这条invoke指令调用的是一个外部的方法, 所以需要到Import Component找到该方法归属的package aid, 以下是”Hello World”应用的Import Component内容:

由此可以获知该方法归属的包的aid为“A0 00 00 00 6201 01”, 即Javacard.f RAMework包, 此时需要以此aid为检索条件寻找到该包的export文件, 并在其中找到对应的方法、完成调用。

而如果调用的是一个静态方法, 如invoke的参数在cp中的内容为06 00 00 01, 则其中“06”为CONSTANT_Static Methodref的tag, 第二个字节“00”表示这是引用一个内部的静态方法, 需要到method component中引用该方法, 最后两个字节“00 01”代表引用的方法在method component中的偏移地址。此时Java卡虚拟机需要再次载入method component表单, 并根据偏移位置载入相应的虚拟机机器码, 完成方法调用。

4.2 Java卡虚拟机优化方法

从上面的分析来看, 不管Java卡虚拟机在实现getstatic_a指令或者invokestatic指令时, 都需要载入、解析和检索cap文件中的多个数据表单。而Java虚拟机操作对象的类型不同, 还支持其他的getxxx和invokexxx指令, 他们的执行流程与getstatic_a指令和invokestatic指令相同。我们可以将这些指令抽象成GET类指令和invoke类指令, 并统一进行优化。

回顾上述这两类指令执行过程的分析:

Get类指令的实现过程需要分别解析Method Component、Constant Pool Component和Static Field Component三张数据表单。

而invoke指令的执行过程更加复杂, 如果是调用的是内部方法, 则需要解析Method Component (2次) 和Constant Pool Component, 而如果要调用的是外部方法, 还需要多解析一次Import Component以及调用的包内的Method Component和Constant Pool Component。

上述所有的component的内容都存储在Flash存储单元中, 读取和解析工作需要多次的Flash读取和擦写操作, 虽然单纯从一条虚拟机指令的执行过程中来看, 耗时还可接受, 但在整个Applet的执行过程中, 会出现上述成千上万次的虚拟机指令的执行, 以及与之对应的、且成倍增加的Flash读写过程, 如此积沙成塔, 必然会拖累Applet整体的执行速度。

因此我们认为针对此类API优化方法的基本思路是:

减少API执行阶段对多个component的读取和解析操作, 以实现降低执行过程中Flash存储器读写操作频率的目的。

为了实现这样的目标, 我们建议:

将原本在Applet执行阶段的component解析操作, 提前到Applet的其他生命周期, 并将解析的结果——被引用成员变量或方法的绝对地址作为参数放置method component的Get和invoke指令后面。

这样在Applet执行的过程中, 每次执行此类函数的速度将大大提高。

下面的问题是:什么时间点才是执行绝对地址解析的最佳触发点?这个触发点应该符合以下2个条件:

1.在整个Applet的生命周期中执行频率相对最低;

2.在这个时间点执行绝对地址解析对用户的感知影响最小。

综合考虑上述两个条件, 我们建议在Applet下载到卡片后, 进行实例化的过程中进行绝对地址的解析操作。由于实例化操作在Applet的整体生命周期中仅会执行一次, 同时, 该执行过程一般是由应用的安装方发起, 对最终用的使用感知基本没有影响。

通过上述方法对Java虚拟机字节码的执行方法进行优化, 以实现Java虚拟机对Java API执行效率的提升。

五、结论

通过前文的论述, 我们不难发现, 由于受制于现有Java卡硬件水平的限制, 不可能将所有的数据放置在RAM中操作, 所以大部分数据仍只能储存在Flash存储器中, 而Flash存储器的操作速度要远远低于RAM存储器, 因此在一定硬件条件基础下, 影响Java API的执行效率的关键因素就是——Flash存储器读写速度慢这一Java卡的硬件瓶颈, 而这也是我们对Java卡虚拟机能效优化的主要着力点。由此我们可以总结出优化Java卡虚拟机运行能效, 提高Java应用执行速度的根本方法——减少API执行阶段对多个component的读取和解析操作, 将解析操作提前到Applet实例化阶段, 并以被引用成员变量或方法的绝对地址作为参数放置method component的Get和invoke指令后面进行解析执行。

摘要:面对日益增多的Java卡应用, 不同智能卡厂家开发的Java卡在使用过程中表现出参差不齐的执行效率。通过对Java卡系统体系和实现方法研究发现, Java卡的执行能效受整体硬件 (CPU、RAM、FLASH等) 、软件 (Java卡虚拟机和Java应用) 条件所影响, 但基于实际的市场环境, 一味提升卡片硬件性能和约束开发方的应用编写习惯, 都不是一个可行、有效的提高运行效率的方法。因此本文将通过解析一个简单Java卡应用实例是如何被Java卡虚拟机解析及执行的过程, 来探讨优化Java卡虚拟机执行效率的简单思

关键词:JAVA卡,虚拟机,执行能效,优化

参考文献

[1]《Virtual Machine Specification Version 3.0.1 Classic Edition》

[2]《Runtime Environment Specification Version 3.0.1 Classic Edition》

[3]《Inside the Java Virtual Machine, Second Edition》

Java虚拟机 第8篇

1 VRML的优缺点

1.1 VRML的概念

虚拟现实建模语言的中文缩写就是VRML, 他是一种以文本为基础的通用编程语言, 也是一种描述三维环境的场景描述语言, 是对于三维的模拟, 在网络上经常会用到。他的诞生改变了原来3W上的平面和单调的缺陷, 将人的行动当成浏览的主体, 即所有的表现都会随着操作者的行为改变而改变, 功能设计更加人性化。VRML直接由浏览器解释执行, 不需要任何编译。当用户打开VRML文件时, 系统会首先装入一个内嵌的VRML浏览器, 该浏览器会的作用是将VRML语言中的信息解释成空间中目标的几何体描述, 如球体, 长方体, 不规则其他三维物体等等, 同时它还有提供实时显示的功能, 且一秒显示多次, 这样用户在操作计算机时会有一个活动场景的感觉。

1.2 VRML的特点

VRML采用的是“可执行的代码”技术, 能够有效地解决网络带宽所造成的问题。VRML性价比也很高。Web浏览器用统一通用的客户端程序, 处理显示来自于不同服务器的数据, 而这些服务器能以不同的格式、不同的协议来传递文件。由于Web应用框架中含有开放标准, 所以客户端程序可以使用HTTP协议访问Java Applet或HTML文件、使用FTP协议下载文件、使用SMTP或POP协议收发Email、通过VRML文件访问3D影象、以及访问许多其他不同的网络资源。现在的C/S应用中很多时候不同的客户端软件会带来隐含费用支出, 而这个通用的客户端程序则消除了这一情形。通用的客户端程序还可以使用户能够用同样的方式与所有基于Web的应用交互, 这样也减少了技术支持和相关的培训费用。所以从以上各方面来看, 基于Web的虚拟产品技术具有良好的性能价格比。另外, 从LAN到Internet的可扩展性相对较好。由于VRML和其他Web程序都有共同的网络通信协议———TCP/IP, 所以基于Web的虚拟产品技术不仅能在小型局域网上应用, 也可以在大型广域网乃至Internet上应用。

1.3 VRML的缺点

首先, 几乎所有的VRML浏览器都是利用拖动鼠标或敲击键盘的箭头用以改变视角的方式来观看VRML世界, 控制手段相对比较不精确, 定位比较困难。其次, VRML和外界的信息互换能力比较差, VRML几乎不和HTML文件进行信息互换, 仅仅是作为一个插件嵌入到网页中的, 所以VRML的数据无法传送到HTML中, HTML也无法读取VRML的数据。最后, VRML与用户的交互界面引对较差, VRML的交互目前还仅仅限于单击或移动鼠标, 没有提供其它的友好用户界面, 特别是它没有提供用户输入数据的功能, 这对于一般的用户, 特别是课件的使用者来说, 都造成了极大的不便。教学课件根据学习者输入的数据信息作出不同的响应, 这点是教学课件必须具备的交互手段之一, 但VRML在这方面就显得无能为力了, 这就大大影响了它在网络课件中的发展进度和空间。

2 JAVL的优点以及缺点

JAVL于1991年被研发问世, 但当时并没有受到人们的普遍重视, 一直到1994年才得到发展。JAVL语言同时具有编译型语言和解释型语言两者的优点, 有着执行效率高、程序的可移植性以及安全性好的特点。首先JAVL是一种针对网络的应用而专门开发的语言, 真正面向对象。并取消了指针的概念, 他由计算机自动管理内存, 所以非常的安全可靠。而且结构标准、移植性高, 具有跨平台性, 同时也具有很高的可拓展性。其次, JAVL可以生成不管是简单还是复杂的形体, 也可以直接调用现有的三维形体;并使形体具有透明效果、颜色、贴图等处理效果;他还可以在三维环境中生成灯光、移动灯光;可以具有键盘、定时、鼠标等行为的处理判断能力;并可生成雾、背景、声音等效果;还可以使形体变形、移动、生成三维动画, 也可以编写非常复杂的应用程序, 用于各种领域, 比如VR。但是, 他的缺点是编程要求复杂, 运行速度缓慢, 所以限制了其自身的发展。

3 通过JAVL和VRML实现虚拟仿真系统

1) 简单的说, 虚拟仿真系统的第一步, 是从CAD系统中创建装配模型, 从CAD中提取出一些模型的相关的信息, 再利用这些信息在虚拟的环境中实现虚拟的装配。所以, 我们要设计一个实用的、可以拓展的虚拟装配平台。与面向对象的编程语言相比, VRML对CAD数据的描述能力也比较有限, VRML2.0中支持的一些简单行为, 可以用JavaScript来完成一些http文件调用的功能和基本的数学功能, 但对于一些相对比较复杂的工作比如场景交互等, 由于网络的程序语言功能和跨平台等原因, 所以当前Java语言基本上是这一应用领域的首选。通过外部编程接口 (EAI) 和内部Script节点使Java与VRML相结合, 应用VRML中的Script节点从VRML场景内部提供了与Java的连接, 来实现与VRML场景的交互。

2) 选择开发工具时, 首先要从成本考量, 具有成本意识, 尽量降低虚拟环境开发的成本, 降低对设计平台的依赖性和进行网络数据传输的要求, 所以由此看来, JAVL和VRML是开发低成本虚拟环境比较有效的途径。

3) JAVL和VRML的交互方法:JAVA属于一种跨平台程式语言, 他能够很好的支持在网络环境下的编程, 而VRM L的优势在于构建虚拟现实场景。解决VRML与JAVA程序之间的交互, 一般采用以下3个方法:第一是通过语言的方法, 就是把VRML的3D数据全部转化为程序语言, 它不仅可以使浏览器得到场景的完整信息, 也具备基本语言的控制结构。不过文件容量过大, 不太适用于网络的传输;第二是E AI的方法, 作为一种应用程序的接口, EAI是基于JAVA和VRML小应用之间的事件传递而提出的一种规则, 他可以用于实现JAVA Applet和VRML中虚拟场景之间的相互通信。EAI几乎囊括了浏览器脚本接口的所有功能, 比如查询浏览器状态、增删路由等, 所以如果需要集成多种媒体, 进行比较复杂的网络控制, 一般都会采用EAI方法进行;第三是SAI的方法, 它是使用路由和事件机制, 也就是说利用事件发生器、script节点、dff/use命名规则和路由route, 来连接VRML场景中对应的域和节点, 用以实现JAVA与VRML的交互, 一般作法为:先通过eventin将事件传至Script节点中的URL字段, 然后再在Scrip节点中的脚本中调用相应的JAVA类来做处理;最后再通过Script节点的evenout事件, 把处理结果送回到VRML场景中, 用以实现动画或交互。这种方法是目前最常用到的一种JAVA和VRML结合用以实现交互的方法。VRML不太考虑对象行为, 比较着重于虚拟场景中对象的特征;而JAVA则很少涉及外部特征, 他主要讨论是对象行为, 所以二者各有千秋, 相互作了很好的补充, 因此普遍都认为VRML与JAVA的结合, 是可以实现相对比较高等级交互功能 (如复杂动态场景控制等) 的有效方法。VRML中使用JAVA有两种方式, 即通过外部授权接口EAI访问以及通过脚本编程接口SAI访问。JAVA能够自由运用于3D场景[3], 获得了一个结合VRML世界和JAVA世界的机制。VRML世界通过其扩展执行模式进入JAVA世界, 即活动行为通过一个特殊结点来连接两个模块。

4) JAVA程序与VRML场景间的连接:JAVA通过他的附加封装类———CLASS来实现对VRML的扩展和支持。类是指所有相似对象的状态变量与行为构成的模板 (template) 或原型 (prototype) 。可以避免冲突出现的包 (package) 中又包含着每一个类和界面的名字。通过这些类, VRML中的所有场景, 在接受和发送事件等各个环节都能被JAVA访问到。目前, JAVA对VRML场景的访问控制有两种方式:第一种是SAI脚本编程接口方式, 也就是说JAVL利用Script, 来实现VRML和JAVL交互的交互流程图本语言;第二种则是EAI外部编程接口来访问。

Applet和VRML场景都内置在超文本标记语言页面上时一般用这种方式连接。在这类情况下, Applet主要利用封装在VRML包中的Broseser类来控制访问场景Browse r类的基类IBroser的接口类, 它封装的内容不仅有VRML场景中除了SAI可使用的函数, 还有getNode () 函数直接获得场景中使用DEF语句定义的节点。与SAI方式相类似, EAI中也可调用geteventout、geteventin来获取那些事件的输出或输入的实例, 从而引起场景的变化。

5) 相对于基于VRML的其他的虚拟仿真系统, 首先它具备快速而且方便的冲突检测机制, 能够执行较为负载的装配操作;其次, 系统具有独立性, 在VRML模型由CAD系统生成后, 在整个装配过程就脱离了对其他CAD系统的依赖, 再也不需要任何CAD系统的支持, 这就加快了系统的运行速度, 实现了系统平台的无关性。另外可以独立的工作, 完全支持网络化协同设计, 也大大的方便了与其他虚拟设计系统的集成。最后可以通过JAVL来实现细腻模型的人机交互控制, 实现虚拟仿真。

随着VRML技术以及JAVL技术的不断完善和发展, VRML和JAVL的交互在人们的日常生活中的功能开发的作用也日益显著, 运用也逐渐增多, 后续将会受到人们越来越多的关注。我们也要不断地解决VRML和JAVL在发展中暴露的问题。可以通过VRML和JAVL在浏览器上进行多场景、多视点的浏览对象, 并运用多种方式、方法来控制场景中物体的运动与交互, 使人感受到逼真的并联机构平台效果, 为基于设计结果的异地评价和Internet的异地协同提供支撑环境, 继续不断的探索在虚拟现实环境中机械机构运动仿真的实现方法。

参考文献

[1]章银娥.基于VRML&JAVL的火灾仿真系统的设计与应用[J].科技广场, 2006 (8) .

[2]张小强.Web3D技术及其在产品仿真系统中的应用[J].重庆大学学报, 2002 (5) .

[3]章银娥.VRML虚拟现实技术在火灾仿真系统的应用[J].赣南师范学院学报, 2006 (6) .

[4]薛强.一个基于JAVL3D的虚拟装配图形仿真系统[J].交通与计算机, 2005 (2) .

上一篇:建筑设计初步下一篇:山水诗歌