本文共 2303 字,大约阅读时间需要 7 分钟。
在类加载器里提到了System与Runtime类,这里就趁热打铁来对这两个源码进行解析,因为System与Runtime关联很紧密,所以就一起来解析吧。
首先来看看System类提供的几个特性: 1、standard input, standard output, and error output streams 2、访问扩展属性和java的环境变量 3、加载本地内库 4、提供一个arraycopy的复制功能 5、获取Console对象 6、获取和设置SecurityManager对象 7、获取本地库文件mapLibraryName方法 该方法示例:System.out.println(System.mapLibraryName("awt")); 打印结果为awt.dll,这个文件存放的路径在JAVA_HOME/jre/bin目录下,大家可以自己试试其他的。 8、JVM退出(exit) 看下Runtime类提供的几个特性: 1、一个JVM对应一个Runtime对象(single) 2、允许访问和调用其他应用程序 3、扩展ShutdownHook 4、获取内存使用相关信息 5、加载本地内库 6、JVM退出(exit) 首先分析下System类,该类有个重要的方法,如下图: 该方法是被JVM调用的,很奇怪吧。当时我也没想明白,这个方法是private,怎么被调用到呢?后来仔细分析后发现,注意这个方法,如下: private static native void registerNatives(); static { registerNatives(); } 该方法会将initializeSystemClass方法映射到本地方法里,方便JVM调用;这里很重要,JNI方便java去调用C++/C的动态连接库。而该方法是让C++/C能调用到java方法。 至于registerNatives方法做了什么更具体的事情,可以去查看源码。 我们来具体分析下initalizeSystemClass做那些事情: 1、初始化out、in、err等流 2、初始化环境变量Properties 3、初始化信号量,Terminator.setup(); 4、sun.misc.VM.initializeOSEnvironment(); OSEnvironment代码如下: 这里就很明显了,主要是设置些错误模式标识,JVM如何处理这样的错误(目前是四种:临界区错误、文件错误、自动修复内存对齐、一般的故障保护)。 5、sun.misc.VM.maxDirectMemory(); 该方法在VM很简单,就是直接return directMemory,该参数的设置与-XX:MaxDirectMemorySize=<size>有关 6、sun.misc.VM.allowArraySyntax(); 在VM也很简单,也是直接返回return allowArraySyntax 7、sun.misc.VM.booted(); 在VM里是将booted赋值为true。 个人认为5、6两个步骤是没有必要的,不知道为什么要调用下。 另外就是如何验证initalizeSystemClass是JVM调用的,很简单,可以参考下out/in/err等属性是如何初始化的。我自己写了模拟例子,如下: class AB{ } final class AB_System{ public static final AB a=nullAB(); private static AB nullAB(){ if (System.currentTimeMillis() > 0) { return null; } throw new NullPointerException(); } static{ System.out.println("ab_system static"); } private AB_System(){ } public static void print(){ System.out.println("abaddd_dadfa"); } } public class Test_System { public static void main(String[] args) { System.out.println(AB_System.a==null); } } 运行结果是true。 再来分析下Runtime类。 因源码里有较多的native方法,所以逻辑比较简单, 这里就是主要是exec这样的方法,可以找些例子操作体验下,就行了。与之相关的时Process类,这个类就是外部被调用的应用程序,在java里的一个代理对象(也可以叫做交互的接口对象,例如返回相关的运行状态等),后面会对这个类进行解析。
还有就是掌握强制终止和正常终止的区别。
关于两者之间的关联 个人认为差别不是很大,因为有很多相同点(System里也有需要调用Runtime里的方法)。 分成两个类,还是因为职责分开吧,System比较倾向于程序员使用(是一个工具类,不能被实例化),而Runtime(是一个single object)更倾向于与JVM和其他应用程序交互。 这两个类主要用于的场景如下: 如何安全的关闭应用程序(换句话说就是java程序退出或者JVM退出),可能很少在写java程序时(特别是java的开源项目众多),要考虑如何关闭JVM的 自定义的SecurityManager类 增加Hook 加载自己的动态链接库等转载地址:http://yvzob.baihongyu.com/