java runtime类

java Runtime类

    博客分类:
  • java编程
Java虚拟机DOSOfficeWindows 

Java的类库日益庞大,所包含的类和接口也不计其数。但其中有一些非常重要的类和接口,是Java类库中的核心部分。常见的有String、Object、Class、Collection、ClassLoader、Runtime、Process...,熟悉这些类是学好Java的基础。而这些类一般不容易理解,需要做深入的研究和实践才能掌握。下面是我对这些类理解和使用的一些总结。欢迎你在阅读后将你宝贵的意见和读后感留下!

一、概述

     Runtime类封装了运行时的环境。每个 Java 应用程序都有一个 Runtime类实例,使应用程序能够与其运行的环境相连接。

     一般不能实例化一个Runtime对象,应用程序也不能创建自己的 Runtime 类实例,但可以通过 getRuntime方法获取当前Runtime运行时对象的引用。

     一旦得到了一个当前的Runtime对象的引用,就可以调用Runtime对象的方法去控制Java虚拟机的状态和行为。

     当Applet和其他不被信任的代码调用任何Runtime方法时,常常会引起SecurityException异常。

二、API预览

   addShutdownHook(Thread hook)

     注册新的虚拟机来关闭挂钩。 www.87717.com

   availableProcessors()

     向 Java 虚拟机返回可用处理器的数目。

    exec(Stringcommand)

     在单独的进程中执行指定的字符串命令。

   exec(String[] cmdarray)

     在单独的进程中执行指定命令和变量。

   exec(String[] cmdarray, String[] envp)

     在指定环境的独立进程中执行指定命令和变量。

   exec(String[] cmdarray, String[] envp, File dir)

     在指定环境和工作目录的独立进程中执行指定的命令和变量。

    exec(Stringcommand, String[] envp)

     在指定环境的单独进程中执行指定的字符串命令。

    exec(Stringcommand, String[] envp, File dir)

     在有指定环境和工作目录的独立进程中执行指定的字符串命令。

    exit(intstatus)

     通过启动虚拟机的关闭序列,终止当前正在运行的 Java 虚拟机。

   freeMemory()

     返回 Java 虚拟机中的空闲内存量。

    gc()

     运行垃圾回收器。

    InputStreamgetLocalizedInputStream(InputStream in)

     已过时。 从 JDK 1.1 开始,将本地编码字节流转换为 Unicode 字符流的首选方法是使用 InputStreamReader和 BufferedReader 类。

    OutputStreamgetLocalizedOutputStream(OutputStream out)

     已过时。 从 JDK 1.1 开始,将 Unicode 字符流转换为本地编码字节流的首选方法是使用OutputStreamWriter、BufferedWriter 和 PrintWriter 类。

   getRuntime()

     返回与当前 Java 应用程序相关的运行时对象。

 

    halt(intstatus)

     强行终止目前正在运行的 Java 虚拟机。

    load(Stringfilename)

     加载作为动态库的指定文件名。

   loadLibrary(String libname)

     加载具有指定库名的动态库。

maxMemory()

     返回 Java 虚拟机试图使用的最大内存量。

   removeShutdownHook(Thread hook)

     取消注册某个先前已注册的虚拟机关闭挂钩。

   runFinalization()

     运行挂起 finalization 的所有对象的终止方法。

   runFinalizersOnExit(value)

     已过时。 此方法本身具有不安全性。它可能对正在使用的对象调用终结方法,而其他线程正在操作这些对象,从而导致不正确的行为或死锁。

   totalMemory()

     返回 Java 虚拟机中的内存总量。

   traceInstructions(on)

     启用/禁用指令跟踪。

   traceMethodCalls(on)

     启用/禁用方法调用跟踪。

三、常见的应用

1、内存管理:

Java提供了无用单元自动收集机制。通过totalMemory()和freeMemory()方法可以知道对象的堆内存有多大,还剩多少。

Java会周期性的回收垃圾对象(未使用的对象),以便释放内存空间。但是如果想先于收集器的下一次指定周期来收集废弃的对象,可以通过调用gc()方法来根据需要运行无用单元收集器。一个很好的试验方法是先调用gc()方法,然后调用freeMemory()方法来查看基本的内存使用情况,接着执行代码,然后再次调用freeMemory()方法看看分配了多少内存。下面的程序演示了这个构想。

class MemoryDemo{

    publicstatic void main(String args[]){

       Runtime r = Runtime.getRuntime();

       long mem1,mem2;

       Integer someints[] = new Integer[1000];

       System.out.println("Total memory is :" + r.totalMemory());

       mem1 = r.freeMemory();

       System.out.println("Initial free is : " + mem1);

       r.gc();

       mem1 = r.freeMemory();

       System.out.println("Free memory after garbage collection : " +mem1);

       //allocate integers

       for(int i=0; i<1000; i++) someints[i] = newInteger(i);

 

       mem2 = r.freeMemory();

       System.out.println("Free memory after allocation : " + mem2);

       System.out.println("Memory used by allocation : "+(mem1-mem2));

 

       //discard Intergers

       for(int i=0; i<1000; i++) someints[i] = null;

       r.gc(); //request garbage collection

       mem2 = r.freeMemory();

       System.out.println("Free memory after collecting " + "discardedintegers : " + mem2);

    }

}

编译后运行结果如下(不同的机器不同时间运行的结果也不一定一样):

Total memory is :2031616

Initial free is : 1818488

Free memory after garbage collection :1888808

Free memory after allocation :1872224

Memory used by allocation : 16584

Free memory after collecting discardedintegers : 1888808

 

2、执行其他程序

在安全的环境中,可以在多任务操作系统中使用Java去执行其他特别大的进程(也就是程序)。ecec()方法有几种形式命名想要运行的程序和它的输入参数。ecec()方法返回一个Process对象,可以使用这个对象控制Java程序与新运行的进程进行交互。ecec()方法本质是依赖于环境。

下面的例子是使用ecec()方法启动windows的记事本notepad。这个例子必须在Windows操作系统上运行。

 

class ExecDemo {

    publicstatic void main(String args[]){

       Runtime r = Runtime.getRuntime();

       Process p = null;

       try{

           p = r.exec("notepad");

       } catch (Exception e) {

           System.out.println("Error executing notepad.");

       }

    }

}

 

ecec()还有其他几种形式,例子中演示的是最常用的一种。ecec()方法返回Process对象后,在新程序开始运行后就可以使用Process的方法了。可以用destory()方法杀死子进程,也可以使用waitFor()方法等待程序直到子程序结束,exitValue()方法返回子进程结束时返回的值。如果没有错误,将返回0,否则返回非0。下面是关于ecec()方法的例子的改进版本。例子被修改为等待,直到运行的进程退出:

class ExecDemoFini {

    publicstatic void main(String args[]){

       Runtime r = Runtime.getRuntime();

       Process p = null;

       try{

           p = r.exec("notepad");

           p.waitFor();

       } catch (Exception e) {

           System.out.println("Error executing notepad.");

       }

       System.out.println("Notepad returned " + p.exitValue());

    }

}

下面是运行的结果(当关闭记事本后,会接着运行程序,打印信息):

Notepad returned 0 www.87717.com

按任意键继续. . .

 

当子进程正在运行时,可以对标准输入输出进行读写。getOutputStream()方法和getInPutStream()方法返回对子进程的标准输入和输出。

 

增加的内容:

Java中使用Runtime和Process类运行外部程序

使用Runtime.getRuntime().exec()方法可以在java程序里运行外部程序。
  1. exec(String command)
  2. exec(String command, String envp[], Filedir)
  3. exec(String cmd, String envp[])
  4. exec(String cmdarray[])
  5. exec(String cmdarray[], String envp[])
  6. exec(String cmdarray[], String envp[], Filedir)
一般的应用程序可以直接使用第一版本,当有环境变量传递的时候使用后面的版本。其中2和6版本可以传递一个目录,标识当前目录,因为有些程序是使用相对目录的,所以就要使用这个版本。

cmd.exe /c start <FileName>
使用DOS命令(比如dir)时也要使用到调用。如果想与调用的程序进行交互,那么就要使用该方法的返回对象Process了,通过Process的getInputStream(),getOutputStream()和getErrorStream()方法可以得到输入输出流,然后通过InputStream可以得到程序对控制台的输出信息,通过OutputStream可以给程序输入指令,这样就达到了程序的交换功能。

用Java编写应用时,有时需要在程序中调用另一个现成的可执行程序或系统命令,这时可以通过组合使用Java提供的Runtime类和Process类的方法实现。下面是一种比较典型的程序模式:

1[转载]Java <wbr>RunTime类 <wbr>(转载)  [转载]Java <wbr>RunTime类 <wbr>(转载)
2[转载]Java <wbr>RunTime类 <wbr>(转载)  Process process = Runtime.getRuntime().exec(".\p.exe"
);
3
[转载]Java <wbr>RunTime类 <wbr>(转载)  process.waitfor();
4[转载]Java <wbr>RunTime类 <wbr>(转载)  [转载]Java <wbr>RunTime类 <wbr>(转载)


在上面的程序中,第一行的“.\p.exe”是要执行的程序名,Runtime.getRuntime()返回当前应用程序的Runtime对象,该对象的exec()方法指示Java虚拟机创建一个子进程执行指定的可执行程序,并返回与该子进程对应的Process对象实例。通过Process可以控制该子进程的执行或获取该子进程的信息。第二条语句的目的等待子进程完成再往下执行。
但在windows平台上,如果处理不当,有时并不能得到预期的结果。下面是笔者在实际编程中总结的几种需要注意的情况:
  1、执行DOS的内部命令
 如果要执行一条DOS内部命令,有两种方法。一种方法是把命令解释器包含在exec()的参数中。例如,执行dir命令,在NT上,可写成exec("cmd.exe  /c dir"),在windows95/98下,可写成“command.exe /cdir”,其中参数“/c”表示命令执行后关闭DOS立即关闭窗口。另一种方法是,把内部命令放在一个批命令my_dir.bat文件中,在Java程序中写成exec("my_dir.bat")。如果仅仅写成exec("dir"),Java虚拟机则会报运行时错误。前一种方法要保证程序的可移植性,需要在程序中读取运行的操作系统平台,以调用不同的命令解释器。后一种方法则不需要做更多的处理。
  2、打开一个不可执行的文件
 打开一个不可执行的文件,但该文件存在关联的应用程序,则可以有两种方式。以打开一个word文档a.doc文件为例,Java中可以有以下两种写法:

1[转载]Java <wbr>RunTime类 <wbr>(转载)  exec("start .\a.doc");
2[转载]Java <wbr>RunTime类 <wbr>(转载)  exec("Files\Microsoft Office\office\winword.exe .\a.doc");

  显然,前一种方法更为简捷方便。
  3、执行一个有标准输出的DOS可执行程序
 在Windows平台上,运行被调用程序的DOS窗口在程序执行完毕后往往并不会自动关闭,从而导致Java应用程序阻塞在waitfor()语句。导致该现象的一个可能的原因是,该可执行程序的标准输出比较多,而运行窗口的标准输出缓冲区不够大。解决的办法是,利用Java中Process类提供的方法让Java虚拟机截获被调用程序的DOS运行窗口的标准输出,在waitfor()命令之前读出窗口的标准输出缓冲区中的内容。一段典型的程序如下:

1[转载]Java <wbr>RunTime类 <wbr>(转载)  [转载]Java <wbr>RunTime类 <wbr>(转载)
2
[转载]Java <wbr>RunTime类 <wbr>(转载)  String s;
3[转载]Java <wbr>RunTime类 <wbr>(转载)  Process process = Runtime.getRuntime().exec("cmd /c dir \windows"
);
4[转载]Java <wbr>RunTime类 <wbr>(转载)  BufferedReader bufferedReader = new BufferedReader(new
 InputStreamReader(process.getInputStream());
5[转载]Java <wbr>RunTime类 <wbr>(转载)  while((s=bufferedReader.readLine()) != null
)
6
[转载]Java <wbr>RunTime类 <wbr>(转载)  System.out.println(s);
7[转载]Java <wbr>RunTime类 <wbr>(转载)  process.waitfor();

你可能感兴趣的:(java,虚拟机,windows,String,dos,Allocation)