System类构造函数由private修饰,不可以被实例化,加载时调用static代码块。
System类提供了标准输入输出流,错误输出流,获取外部属性和系统环境的方法,加载类库和文件的方法,快速copy数组的方法;其中out和err的类型是PrintStream
/** * The <code>System</code> class contains several useful class fields * and methods. It cannot be instantiated. * * <p>Among the facilities provided by the <code>System</code> class * are standard input, standard output, and error output streams; * access to externally defined properties and environment * variables; a means of loading files and libraries; and a utility * method for quickly copying a portion of an array. * * @author unascribed * @since JDK1.0 */ public final class System { /* register the natives via the static initializer. * * VM will invoke the initializeSystemClass method to complete * the initialization for this class separated from clinit. * Note that to use properties set by the VM, see the constraints * described in the initializeSystemClass method. */ private static native void registerNatives(); static { registerNatives(); } /** Don't let anyone instantiate this class */ private System() { }
System.exit(int),终止当前虚拟机的运行,什么叫做当前虚拟机呢?
public static void exit(int status) { Runtime.getRuntime().exit(status); }
如果在某个线程中调用了exit会怎样?下面的例子输出结果是hello,把子线程和主线程的内容交换也是一样的结果。就是说不管在哪个线程调用了exit,整个应用都退出了。
package com.ysdx.test; public class JavaTest { public static void main(String[] args) { Thread thread = new Thread(() -> { try { Thread.sleep(1000); } catch (InterruptedException e) { // TODO Auto-generated catch block e.printStackTrace(); } System.out.println("hello!"); System.exit(1); }); thread.start(); try { Thread.sleep(3000); } catch (InterruptedException e) { // TODO Auto-generated catch block e.printStackTrace(); } System.out.println("Hello from main thread!"); } }
两个虚拟机之间是互不影响的
其中JavaTest1如下
public class JavaTest1 { public static void main(String[] args) { try { Thread.sleep(3000); } catch (InterruptedException e) { // TODO Auto-generated catch block e.printStackTrace(); } System.out.println("Hello from main thread!"); } }
---------------------
System中gc相关操作
/** * Runs the garbage collector. * <p> * Calling the <code>gc</code> method suggests that the Java Virtual * Machine expend effort toward recycling unused objects in order to * make the memory they currently occupy available for quick reuse. * When control returns from the method call, the Java Virtual * Machine has made a best effort to reclaim space from all discarded * objects. * <p> * The call <code>System.gc()</code> is effectively equivalent to the * call: * <blockquote><pre> * Runtime.getRuntime().gc() * </pre></blockquote> * * @see java.lang.Runtime#gc() */ public static void gc() { Runtime.getRuntime().gc(); } /** * Runs the finalization methods of any objects pending finalization. * <p> * Calling this method suggests that the Java Virtual Machine expend * effort toward running the <code>finalize</code> methods of objects * that have been found to be discarded but whose <code>finalize</code> * methods have not yet been run. When control returns from the * method call, the Java Virtual Machine has made a best effort to * complete all outstanding finalizations. * <p> * The call <code>System.runFinalization()</code> is effectively * equivalent to the call: * <blockquote><pre> * Runtime.getRuntime().runFinalization() * </pre></blockquote> * * @see java.lang.Runtime#runFinalization() */ public static void runFinalization() { Runtime.getRuntime().runFinalization(); }
顺便看一下Runtime,
即便不显示调用gc,JVM也会自动在一个单独的线程中执行recycling process;
即便不显示调用runFinalization,JVM也会自动在一个单独的线程中执行finalization process;
可以很明显的看出gc和runFinalization是不同的,一个叫做回收过程,一个叫做终结过程。
调用runFinalization后,终结过程会调用已经被废弃但是尚未调用其finalization方法的对象。
函数注释里的描述都使用了suggest和has made its best effort,可能这两个函数还有不足之处。
/** * Runs the garbage collector. * Calling this method suggests that the Java virtual machine expend * effort toward recycling unused objects in order to make the memory * they currently occupy available for quick reuse. When control * returns from the method call, the virtual machine has made * its best effort to recycle all discarded objects. * <p> * The name <code>gc</code> stands for "garbage * collector". The virtual machine performs this recycling * process automatically as needed, in a separate thread, even if the * <code>gc</code> method is not invoked explicitly. * <p> * The method {@link System#gc()} is the conventional and convenient * means of invoking this method. */ public native void gc(); /* Wormhole for calling java.lang.ref.Finalizer.runFinalization */ private static native void runFinalization0(); /** * Runs the finalization methods of any objects pending finalization. * Calling this method suggests that the Java virtual machine expend * effort toward running the <code>finalize</code> methods of objects * that have been found to be discarded but whose <code>finalize</code> * methods have not yet been run. When control returns from the * method call, the virtual machine has made a best effort to * complete all outstanding finalizations. * <p> * The virtual machine performs the finalization process * automatically as needed, in a separate thread, if the * <code>runFinalization</code> method is not invoked explicitly. * <p> * The method {@link System#runFinalization()} is the conventional * and convenient means of invoking this method. * * @see java.lang.Object#finalize() */ public void runFinalization() { runFinalization0(); }
System中获取系统变量的方法:
getenv(String name)返回跟name对应的变量值;
getenv(),这个函数返回一个不可修改的、包含系统变量名和对应值的map,这个map在ProcessEnvironment中声明:private static final Map<String,String> theUnmodifiableEnvironment;
public static String getenv(String name) { SecurityManager sm = getSecurityManager(); if (sm != null) { sm.checkPermission(new RuntimePermission("getenv."+name)); } return ProcessEnvironment.getenv(name); } public static java.util.Map<String,String> getenv() { SecurityManager sm = getSecurityManager(); if (sm != null) { sm.checkPermission(new RuntimePermission("getenv.*")); } return ProcessEnvironment.getenv(); }
System类关于系统属性的操作有get、set和clear方法,而Environment只有读取的函数。
environment是操作系统环境变量信息,property感觉更像是jvm相关参数。下面例子的输出结果是:
java.runtime.name = Java(TM) SE Runtime Environment sun.boot.library.path = C:Program FilesJavajre1.8.0_121in java.vm.version = 25.121-b13 java.vm.vendor = Oracle Corporation java.vendor.url = http://java.oracle.com/ path.separator = ; java.vm.name = Java HotSpot(TM) 64-Bit Server VM file.encoding.pkg = sun.io user.script = user.country = CN sun.java.launcher = SUN_STANDARD sun.os.patch.level = java.vm.specification.name = Java Virtual Machine Specification user.dir = F:CodingSource eon-workspaceJavaSystem java.runtime.version = 1.8.0_121-b13 java.awt.graphicsenv = sun.awt.Win32GraphicsEnvironment java.endorsed.dirs = C:Program FilesJavajre1.8.0_121libendorsed os.arch = amd64 java.io.tmpdir = C:UsersADMINI~1AppDataLocalTemp line.separator = java.vm.specification.vendor = Oracle Corporation user.variant = os.name = Windows 8 sun.jnu.encoding = GBK java.library.path = C:Program FilesJavajre1.8.0_121in;C:WindowsSunJavain;C:Windowssystem32;C:Windows;C:/Program Files/Java/jre1.8.0_121/bin/server;C:/Program Files/Java/jre1.8.0_121/bin;C:/Program Files/Java/jre1.8.0_121/lib/amd64;E:CodingIDEPython36Scripts;E:CodingIDEPython36;E:CodingIDEDataBaseoraclexeapporacleproduct11.2.0serverin;;C:ProgramDataOracleJavajavapath;C:Windowssystem32;C:Windows;C:WindowsSystem32Wbem;C:WindowsSystem32WindowsPowerShellv1.0;C:Program FilesJavajdk1.8.0_121in;C:Program FilesJavajdk1.8.0_121jrein;E:CodingIDEDataBasemysql-5.7.17-winx64in;E:CodingIDEeclipse-jee-neon-3-RC3-win32-x86_64eclipse;;. java.specification.name = Java Platform API Specification java.class.version = 52.0 sun.management.compiler = HotSpot 64-Bit Tiered Compilers os.version = 6.2 user.home = C:UsersAdministrator user.timezone = java.awt.printerjob = sun.awt.windows.WPrinterJob file.encoding = GBK java.specification.version = 1.8 user.name = Administrator java.class.path = F:CodingSource eon-workspaceJavaSystemin java.vm.specification.version = 1.8 sun.arch.data.model = 64 java.home = C:Program FilesJavajre1.8.0_121 sun.java.command = com.ysdx.jsys.JavaSystem java.specification.vendor = Oracle Corporation user.language = zh awt.toolkit = sun.awt.windows.WToolkit java.vm.info = mixed mode java.version = 1.8.0_121 java.ext.dirs = C:Program FilesJavajre1.8.0_121libext;C:WindowsSunJavalibext sun.boot.class.path = C:Program FilesJavajre1.8.0_121lib esources.jar;C:Program FilesJavajre1.8.0_121lib t.jar;C:Program FilesJavajre1.8.0_121libsunrsasign.jar;C:Program FilesJavajre1.8.0_121libjsse.jar;C:Program FilesJavajre1.8.0_121libjce.jar;C:Program FilesJavajre1.8.0_121libcharsets.jar;C:Program FilesJavajre1.8.0_121libjfr.jar;C:Program FilesJavajre1.8.0_121classes java.vendor = Oracle Corporation file.separator = java.vendor.url.bug = http://bugreport.sun.com/bugreport/ sun.cpu.endian = little sun.io.unicode.encoding = UnicodeLittle sun.desktop = windows sun.cpu.isalist = amd64 ----------------------------------- USERDOMAIN_ROAMINGPROFILE=PC-201703120850 LOCALAPPDATA=C:UsersAdministratorAppDataLocal PROCESSOR_LEVEL=6 FP_NO_HOST_CHECK=NO USERDOMAIN=PC-201703120850 LOGONSERVER=\PC-201703120850 JAVA_HOME=C:Program FilesJavajdk1.8.0_121 SESSIONNAME=Console ALLUSERSPROFILE=C:ProgramData PROCESSOR_ARCHITECTURE=AMD64 PSModulePath=C:Windowssystem32WindowsPowerShellv1.0Modules #envTSLOGSHELLEXT3464=510784384 SystemDrive=C: =C:=C: APPDATA=C:UsersAdministratorAppDataRoaming USERNAME=Administrator ProgramFiles(x86)=C:Program Files (x86) VBOX_MSI_INSTALL_PATH=F:VirtualBox CommonProgramFiles=C:Program FilesCommon Files Path=C:/Program Files/Java/jre1.8.0_121/bin/server;C:/Program Files/Java/jre1.8.0_121/bin;C:/Program Files/Java/jre1.8.0_121/lib/amd64;E:CodingIDEPython36Scripts;E:CodingIDEPython36;E:CodingIDEDataBaseoraclexeapporacleproduct11.2.0serverin;;C:ProgramDataOracleJavajavapath;C:Windowssystem32;C:Windows;C:WindowsSystem32Wbem;C:WindowsSystem32WindowsPowerShellv1.0;C:Program FilesJavajdk1.8.0_121in;C:Program FilesJavajdk1.8.0_121jrein;E:CodingIDEDataBasemysql-5.7.17-winx64in;E:CodingIDEeclipse-jee-neon-3-RC3-win32-x86_64eclipse; PATHEXT=.COM;.EXE;.BAT;.CMD;.VBS;.VBE;.JS;.JSE;.WSF;.WSH;.MSC;.PY;.PYW OS=Windows_NT COMPUTERNAME=PC-201703120850 PROCESSOR_REVISION=3a09 CommonProgramW6432=C:Program FilesCommon Files #envTSLOGsss3464=166647136 ComSpec=C:Windowssystem32cmd.exe #envTSLOGXMediaLibrary3464=166645216 ProgramData=C:ProgramData =F:=F: ProgramW6432=C:Program Files HOMEPATH=UsersAdministrator SystemRoot=C:Windows TEMP=C:UsersADMINI~1AppDataLocalTemp HOMEDRIVE=C: PROCESSOR_IDENTIFIER=Intel64 Family 6 Model 58 Stepping 9, GenuineIntel USERPROFILE=C:UsersAdministrator TMP=C:UsersADMINI~1AppDataLocalTemp CommonProgramFiles(x86)=C:Program Files (x86)Common Files ProgramFiles=C:Program Files PUBLIC=C:UsersPublic NUMBER_OF_PROCESSORS=4 windir=C:Windows #envTSLOGTSLOG3464=166646496 =::=::
package com.ysdx.jsys; import java.util.Enumeration; import java.util.Map; import java.util.Properties; public class JavaSystem { public static void main(String[] args) { Properties properties = System.getProperties(); Enumeration<?> propertyNames = properties.propertyNames(); for (; propertyNames.hasMoreElements();) { String propertyName = (String) propertyNames.nextElement(); System.out.println(propertyName + " = " + properties.getProperty(propertyName)); } System.out.println("-----------------------------------"); Map<String, String> map = System.getenv(); for (String key : map.keySet()) { System.out.println(key + "=" + map.get(key)); } } }