Android中Runtime类解析及finalize()讲解

来源:互联网 发布:淘宝网行业分析 编辑:程序博客网 时间:2024/05/20 04:29

在Android中有一个Runtime类,这个类主要是用来让Java应用程序可以与它所在的运行环境进行交互,我们的应用不能创建这个类的实例,如果我们希望得到这个实例的话,直接调用Runtime的静态方法来得到这个类的实例。

1、获取Runtime实例
Runtime runtime = Runtime.getRuntime();

2、调用相应的函数操作

下面我们来看看它里面有哪些函数?

public void addShutdownHook (Thread hook)

注册一个VM关闭钩子,这个钩子是一个Thread,注册进去之后,当VM正常终止的时候,例如调用了exit()方法,注册的钩子就会被运行。

public boolean removeShutdownHook (Thread hook)

取消注册VM钩子

public int availableProcessors ()

得到VM可用的处理器内核数,至少为1

public Process exec (String[] progArray, String[] envp)

在单独的本地进程中执行指定的可带参数的命令,其中progArray为需要执行的程序和参数;envp为启动一个新进程的所包含的环境参数。

public Process exec (String[] progArray, String[] envp, File directory)

同上,directory为执行程序所在的目录。

public Process exec (String prog, String[] envp, File directory)

同上,只是这里的程序不带参数

public Process exec (String prog, String[] envp)

同上,只是这里的程序不带参数

public Process exec (String prog)

同上,只是这里的新进程的运行环境继承自调用者。

public Process exec (String[] progArray)

同上

public void exit (int code)

使VM停止运行,并且程序退出

public long freeMemory ()

得到当前堆中可用的空间byte

public void gc ()

提示VM去进行垃圾回收,它只是提示,并不能保证垃圾回收器一定会被执行

public InputStream getLocalizedInputStream (InputStream stream)

返回本地版本的指定输入流

public OutputStream getLocalizedOutputStream (OutputStream stream)

返回本地版本指定的输出流

public void halt (int code)

使VM停止运行,程序会退出带有指定的返回码。

public void load (String absolutePath)

载入指定路径的共享库,例如:/path/to/library/libMyLibrary.so,可以使用loadLibrary(String)使系统找到正确的文件进行载入。

public void loadLibrary (String nickname)

同上

public long maxMemory ()

返回当前堆可以扩展到的最大数目

public void runFinalization ()

提示Runtme去优化所有显式的finalization对象。

public static void runFinalizersOnExit (boolean run)

是否在Runtime退出时结束所有对象

public long totalMemory ()

返回当前堆栈的大小

public void traceInstructions (boolean enable)

是否将debug信息输出转换为指令的形式,在Android中这个方法并不是做什么事。

public void traceMethodCalls (boolean enable)

是否转换debug信息输出为方法的形式

上面有两个函数:runFinalization和runFinalizersOnExit,可能大家会比较疑惑,下面就来讲讲Object中的finalize()方法,你就会明白上面的两个方法。

在Object类里面,有一个方法finalize()。
当VM的垃圾收集器检测到这个对象不可达的时候,也就是说这个对象为垃圾可以被回收的时候,这个对象的finalize ()方法就会被执行,默认情况下,它不做任何处理,我们可以重写这个方法来进行资源的释放。一般不建议使用这个,因为它的代价比较大。

当回收分配的Object对象的内存之前垃圾收集器会调用对象的finalize()方法。但是对于这个方法,我们还需要了解以下几点:

finalize()并不能确保被调用

下面来举个例子:

public class TryCatchFinallyTest implements Runnable {    private void testMethod() throws InterruptedException    {        try        {            System.out.println("In try block");            throw new NullPointerException();        }        catch(NullPointerException npe)        {            System.out.println("In catch block");        }        finally        {            System.out.println("In finally block");        }    }    @Override    protected void finalize() throws Throwable {        System.out.println("In finalize block");        super.finalize();    }    @Override    public void run() {        try {            testMethod();        } catch (InterruptedException e) {            e.printStackTrace();        }    }}public class TestMain{    @SuppressWarnings("deprecation")    public static void main(String[] args) {    for(int i=1;i<=3;i++)    {        new Thread(new TryCatchFinallyTest()).start();    }    }}
Output:In try blockIn catch blockIn finally blockIn try blockIn catch blockIn finally blockIn try blockIn catch blockIn finally block

从上面我们可以看到,finalize()方法并没有被调用。如果希望它能够被调用到,我们需要使用Runtime.runFinalizersOnExit(true)去明确指出才行。

public class TestMain{    @SuppressWarnings("deprecation")    public static void main(String[] args) {        for(int i=1;i<=3;i++)        {            new Thread(new TryCatchFinallyTest()).start();            Runtime.runFinalizersOnExit(true);        }    }}
Output:In try blockIn catch blockIn finally blockIn try blockIn try blockIn catch blockIn finally blockIn catch blockIn finally blockIn finalize blockIn finalize blockIn finalize block

从上面我们可以看到这个时候才能确保它被执行到,但是有些遗憾的的是Runtime.runFinalizersOnExit(true)已经被废弃到了,因为他不是线程安全的。
另外,我们也可以使用Runtime.getRuntime().runFinalization(),但是它只能保证GC尽最大努力去做这个,也不能确保finalize的执行。还有一点就是finalize()方法会影响性能,使用它的代价比较大。

如果我们确实要使用需要注意:
1、在你的finalize()方法中要记得调用super.finalize()。
2、不要把耗时逻辑放在finalize()里面。
3、不要使用Runtime.runFinalizersOnExit(true),因为它可能是你的系统出于危险状态。
4、按照下面的模板来使用finalize方法。

@Overrideprotected void finalize() throws Throwable{    try{        //release resources here    }catch(Throwable t){        throw t;    }finally{        super.finalize();    }}

官方说明:
http://developer.android.com/reference/java/lang/Runtime.html

http://developer.android.com/reference/java/lang/Object.html#finalize()

参考文章:
Why not to use finalize() method in java

0 1
原创粉丝点击