Runtime源码解析(JDK1.8)
package java.lang;
import sun.reflect.CallerSensitive;
import sun.reflect.Reflection;
import java.io.File;
import java.io.IOException;
import java.io.InputStream;
import java.io.OutputStream;
import java.util.StringTokenizer;
/**
* Runtime类,里面可以获得应用运行时的一些状态(主要包括使用的内存和cpu个数)和在应用运行时执行一些操作(程序退出、执行gc、设置退出时的钩子函数)。
* 用到了单例模式:确保一个类最多只有一个实例,并提供一个全局访问点。
*/
public class Runtime {
private static Runtime currentRuntime = new Runtime();
/**
* 应用了设计模式中的单例模式饿汉式(线程安全)
* 返回与当前应用程序相关的java运行时对象。
*/
public static Runtime getRuntime() {
return currentRuntime;
}
/**
* 私有构造函数,单例模式的条件,返回与当前应用程序相关的java运行时对象,不支持new的Runtime
*/
private Runtime() {
}
/**
* 通过启动虚拟机的关闭序列,终止当前正在运行的 Java 虚拟机。此方法从不正常返回。可以将变量作为一个状态码;根据惯例,非零的状态码表示非正常终止。
* 虚拟机的关闭序列包含两个阶段。在第一个阶段中,会以某种未指定的顺序启动所有已注册的关闭钩子(hook)(如果有的话),并且允许它们同时运行直至结束。
* 在第二个阶段中,如果已启用退出终结,则运行所有未调用的终结方法。一旦完成这个阶段,虚拟机就会暂停。
* 如果在虚拟机已开始其关闭序列后才调用此方法,那么若正在运行关闭钩子,则将无限期地阻断此方法。
* 如果已经运行完关闭钩子,并且已启用退出终结 (on-exitfinalization),那么此方法将利用给定的状态码(如果状态码是非零值)暂停虚拟机;否则将无限期地阻断虚拟机。
*/
public void exit(int status) {
SecurityManager security = System.getSecurityManager();
if (security != null) {
security.checkExit(status);
}
Shutdown.exit(status);
}
/**
* 注册新的虚拟机来关闭钩子。
*/
public void addShutdownHook(Thread hook) {
SecurityManager sm = System.getSecurityManager();
if (sm != null) {
sm.checkPermission(new RuntimePermission("shutdownHooks"));
}
ApplicationShutdownHooks.add(hook);
}
/**
* 取消注册某个先前已注册的虚拟机关闭钩子。
* 如果指定的钩子先前已注册并且成功地取消注册,则返回 true,其他情况返回 false。
*/
public boolean removeShutdownHook(Thread hook) {
SecurityManager sm = System.getSecurityManager();
if (sm != null) {
sm.checkPermission(new RuntimePermission("shutdownHooks"));
}
return ApplicationShutdownHooks.remove(hook);
}
/**
* 强行终止目前正在运行的 Java 虚拟机。此方法从不正常返回。
* 应小心使用此方法。与 exit方法不同,此方法不会启动关闭钩子,并且如果已启用退出终结,此方法也不会运行未调用的终结方法。
* 如果已经发起关闭序列,那么此方法不会等待所有正在运行的关闭钩子或终结方法完成其工作。
*/
public void halt(int status) {
SecurityManager sm = System.getSecurityManager();
if (sm != null) {
sm.checkExit(status);
}
Shutdown.halt(status);
}
/**
* 在退出时启用或禁用终结;这样做可指定拥有未被自动调用终结方法的所有对象的终结方法,并将在退出 Java 运行时前运行此终结方法。默认情况下,禁用退出终结。
* 如果有安全管理器,则首先使用 0 作为变量来调用其 checkExit 方法,以确保允许退出。这可能会导致 SecurityException。
*/
@Deprecated
public static void runFinalizersOnExit(boolean value) {
SecurityManager security = System.getSecurityManager();
if (security != null) {
try {
security.checkExit(0);
} catch (SecurityException e) {
throw new SecurityException("runFinalizersOnExit");
}
}
Shutdown.setRunFinalizersOnExit(value);
}
/**
* 在单独的进程中执行指定的字符串命令。
* 对于 exec(command) 形式的调用而言,其行为与调用 exec(command, null, null) 完全相同。
*/
public Process exec(String command) throws IOException {
return exec(command, null, null);
}
/**
* 在指定环境的单独进程中执行指定的字符串命令。
* 对于 exec(command, envp) 形式的调用而言,其行为与调用 exec(command, envp, null) 完全相同。
*/
public Process exec(String command, String[] envp) throws IOException {
return exec(command, envp, null);
}
/**
* 在有指定环境和工作目录的独立进程中执行指定的字符串命令。
* 对于 exec(command, envp, dir) 形式的调用而言,其行为与调用 exec(cmdarray, envp, dir) 完全相同,其中 cmdarray 是 command 中所有标记的数组。
* 更准确地说,可以使用通过调用 new StringTokenizer(command) 创建的 StringTokenizer 将 command 字符串拆解成标记,调用时不对字符类别做进一步的修改。
* 然后将标记生成器所生成的标记以相同的顺序放入新的字符串数组 cmdarray 中。
*/
public Process exec(String command, String[] envp, File dir)
throws IOException {
if (command.length() == 0)
throw new IllegalArgumentException("Empty command");
StringTokenizer st = new StringTokenizer(command);
String[] cmdarray = new String[st.countTokens()];
for (int i = 0; st.hasMoreTokens(); i++)
cmdarray[i] = st.nextToken();
return exec(cmdarray, envp, dir);
}
/**
* 在单独的进程中执行指定命令和变量。
* 对于 exec(cmdarray) 形式的调用而言,其行为与调用 exec(cmdarray, null, null) 完全相同。
*/
public Process exec(String cmdarray[]) throws IOException {
return exec(cmdarray, null, null);
}
/**
* 在指定环境的独立进程中执行指定命令和变量。
* 对于 exec(cmdarray, envp) 形式的调用而言,其行为与调用 exec(cmdarray, envp, null) 完全相同。
*/
public Process exec(String[] cmdarray, String[] envp) throws IOException {
return exec(cmdarray, envp, null);
}
/**
* 在指定环境和工作目录的独立进程中执行指定的命令和变量。
* 给定的字符串数组 cmdarray 表示一个命令行标记,字符串数组 envp 则表示“环境”变量设置,此方法会创建一个新进程,而指定的命令就在这个进程中执行。
* 此方法检查 cmdarray 是否是一条有效的操作系统命令。哪些命令有效取决于系统,但是该命令至少必须有一个非 null 字符串的非空列表。
*/
public Process exec(String[] cmdarray, String[] envp, File dir)
throws IOException {
return new ProcessBuilder(cmdarray)
.environment(envp)
.directory(dir)
.start();
}
/**
* 向 Java 虚拟机返回可用处理器的数目。
* 该值在特定的虚拟机调用期间可能发生更改。因此,对可用处理器数目很敏感的应用程序应该不定期地轮询该属性,并相应地调整其资源用法。
* 虚拟机可用的最大处理器数目;从不小于 1
*/
public native int availableProcessors();
/**
* 返回 Java 虚拟机中的空闲内存量。调用 gc 方法可能导致 freeMemory 返回值的增加。
*/
public native long freeMemory();
/**
* 返回 Java 虚拟机中的内存总量。此方法返回的值可能随时间的推移而变化,这取决于主机环境。
*/
public native long totalMemory();
/**
* 返回 Java 虚拟机试图使用的最大内存量。如果内存本身没有限制,则返回值 Long.MAX_VALUE。
*/
public native long maxMemory();
/**
* 运行垃圾回收器。调用此方法意味着 Java 虚拟机做了一些努力来回收未用对象,以便能够快速地重用这些对象当前占用的内存。
* 当控制从方法调用中返回时,虚拟机已经尽最大努力回收了所有丢弃的对象。
* 垃圾回收机制主要有两类:引用计数收集器 跟踪收集器
*/
public native void gc();
/* Wormhole for calling java.lang.ref.Finalizer.runFinalization */
private static native void runFinalization0();
/**
* 运行挂起 finalization 的所有对象的终止方法。
* 调用此方法意味着 Java 虚拟机做了一些努力运行已被丢弃对象的 finalize 方法,
* 但是这些对象的 finalize 方法还没有运行。当控制从方法调用中返回时,Java 虚拟机已经尽最大努力去完成所有未执行的终止方法。
* 如果不显式调用 runFinalization 方法,则 Java 虚拟机会根据需要在单独的线程中自动执行此终止过程。
*/
public void runFinalization() {
runFinalization0();
}
/**
* 启用/禁用指令跟踪。
*/
public native void traceInstructions(boolean on);
/**
* 启用/禁用方法调用跟踪。
*/
public native void traceMethodCalls(boolean on);
/**
* 加载具有指定动态库。
*/
@CallerSensitive
public void load(String filename) {
load0(Reflection.getCallerClass(), filename);
}
synchronized void load0(Class<?> fromClass, String filename) {
SecurityManager security = System.getSecurityManager();
if (security != null) {
security.checkLink(filename);
}
if (!(new File(filename).isAbsolute())) {
throw new UnsatisfiedLinkError(
"Expecting an absolute path of the library: " + filename);
}
ClassLoader.loadLibrary(fromClass, filename, true);
}
/**
* 加载具有指定动态库。
*/
@CallerSensitive
public void loadLibrary(String libname) {
loadLibrary0(Reflection.getCallerClass(), libname);
}
synchronized void loadLibrary0(Class<?> fromClass, String libname) {
SecurityManager security = System.getSecurityManager();
if (security != null) {
security.checkLink(libname);
}
if (libname.indexOf((int) File.separatorChar) != -1) {
throw new UnsatisfiedLinkError(
"Directory separator should not appear in library name: " + libname);
}
ClassLoader.loadLibrary(fromClass, libname, false);
}
/**
* 创建输入流的本地化版本。此方法获取 InputStream,并返回除本地化外其他所有方面都和变量等效的 InputStream,这些方面包括:作为本地字符集中的字符从流中被读取,并将它们从本地字符集自动转换为 Unicode。
*/
@Deprecated
public InputStream getLocalizedInputStream(InputStream in) {
return in;
}
/**
* 创建输出流的本地化版本。此方法获取 OutputStream,并返回除本地化外其他所有方面都和变量等效的 OutputStream,这些方面包括:作为 Unicode 字符被写入流中,并被自动转换为本地字符集。
* 如果参数已经是本地流,则可作为结果返回。
*/
@Deprecated
public OutputStream getLocalizedOutputStream(OutputStream out) {
return out;
}
}
Runtime源码解析(JDK1.8)的更多相关文章
- 源码解析JDK1.8-HashMap链表成环的问题解决方案
前言 上篇文章详解介绍了HashMap在JDK1.7版本中链表成环的原因,今天介绍下JDK1.8针对HashMap线程安全问题的解决方案. jdk1.8 扩容源码解析 public class Has ...
- Java集合-ArrayList源码解析-JDK1.8
◆ ArrayList简介 ◆ ArrayList 是一个数组队列,相当于 动态数组.与Java中的数组相比,它的容量能动态增长.它继承于AbstractList,实现了List, RandomAcc ...
- ArrayList、CopyOnWriteArrayList源码解析(JDK1.8)
本篇文章主要是学习后的知识记录,存在不足,或许不够深入,还请谅解. 目录 ArrayList源码解析 ArrayList中的变量 ArrayList构造函数 ArrayList中的add方法 Arra ...
- Map集合类(一.hashMap源码解析jdk1.8)
java集合笔记一 java集合笔记二 java集合笔记三 jdk 8 之前,其内部是由数组+链表来实现的,而 jdk 8 对于链表长度超过 8 的链表将转储为红黑树 1.属性 //节点数组,第一次使 ...
- JDK1.8 动态代理机制及源码解析
动态代理 a) jdk 动态代理 Proxy, 核心思想:通过实现被代理类的所有接口,生成一个字节码文件后构造一个代理对象,通过持有反射构造被代理类的一个实例,再通过invoke反射调用被代理类实例的 ...
- Java并发包源码学习系列:JDK1.8的ConcurrentHashMap源码解析
目录 为什么要使用ConcurrentHashMap? ConcurrentHashMap的结构特点 Java8之前 Java8之后 基本常量 重要成员变量 构造方法 tableSizeFor put ...
- 给jdk写注释系列之jdk1.6容器(12)-PriorityQueue源码解析
PriorityQueue是一种什么样的容器呢?看过前面的几个jdk容器分析的话,看到Queue这个单词你一定会,哦~这是一种队列.是的,PriorityQueue是一种队列,但是它又是一种什么样的队 ...
- 给jdk写注释系列之jdk1.6容器(11)-Queue之ArrayDeque源码解析
前面讲了Stack是一种先进后出的数据结构:栈,那么对应的Queue是一种先进先出(First In First Out)的数据结构:队列. 对比一下Stack,Queue是一种先进先出的容 ...
- 给jdk写注释系列之jdk1.6容器(10)-Stack&Vector源码解析
前面我们已经接触过几种数据结构了,有数组.链表.Hash表.红黑树(二叉查询树),今天再来看另外一种数据结构:栈. 什么是栈呢,我就不找它具体的定义了,直接举个例子,栈就相当于一个很窄的木桶 ...
随机推荐
- 使用TensorFlow的卷积神经网络识别自己的单个手写数字,填坑总结
折腾了几天,爬了大大小小若干的坑,特记录如下.代码在最后面. 环境: Python3.6.4 + TensorFlow 1.5.1 + Win7 64位 + I5 3570 CPU 方法: 先用MNI ...
- tcp/ip 卷一 读书笔记(2)物理层和链路层网络
物理层和链路层网络 术语 链路 是一对相邻结点间的物理线路,中间没有任何其他的交换结点. 数据链路 除了物理线路外,还必须有通信协议来控制这些数据的传输. 帧 数据链路层的协议数据单元(PDU) 串行 ...
- NLP+语义分析(四)︱中文语义分析研究现状(CIPS2016、角色标注、篇章分析)
摘录自:CIPS2016 中文信息处理报告<第二章 语义分析研究进展. 现状及趋势>P14 CIPS2016> 中文信息处理报告下载链接:http://cips-upload.bj. ...
- Android 网络之 Volley+OkHttp+Https
Volley 已经发布很长时间了, 也已被广泛应用, 相关教程到处都是. 本文只说两个值得注意的地方. 本文讲解部分比较少, 请参阅提供的相关链接. 完整的实现代码在 Github dodocat/A ...
- jQuery提示parsererror错误解决办法
jquery来处理ajax,用到了json.但是很诧异,jquery的ajax回调时一直调用了error函数(一直提示parsererror异常),success函数一次没执行过 $.ajax({ t ...
- FusionCharts报错收录
FusionCharts报错 1.错误一 DesignTimeError:#25081843 flash-chart render Error >>#25081843:IECompatib ...
- printk优先级
printk是在内核中运行的向控制台输出显示的函数,Linux内核首先在内核空间分配一个静态缓冲区,作为显示用的空间,然后调用sprintf,格式化显示字符串,最后调用tty_write向终端进行信息 ...
- 错误代码: 1327 Undeclared variable: p_film_count
1.错误描述 1 queries executed, 0 success, 1 errors, 0 warnings 查询:SELECT FOUND_ROWS() INTO p_film_count ...
- java.sql.SQLException:Column count doesn't match value count at row 1
1.错误描述 java.sql.SQLException:Column count doesn't match value count at row 1 2.错误原因 在插入数据时,插入的字段 ...
- java实现取球类的博弈问题
1.问题描述: 今盒子中有n个小球,A,B两人轮流从盒子中取球,每个人都可以看到对方的取球数目. 规定如下: 取球只能取1,3,7,8四种情况.如果没有球取了,则输了.规定A先取球,给定初始球的数目, ...