【知识回顾】Java常用类库-Java Runtime

news2024/12/25 3:34:04

在这里插入图片描述

文章目录

  • 一、快速入门
    • 1.1 Runtime 介绍
    • 1.2 常用方法
      • 1.2.1 基本方法
      • 1.2.2 行为控制类
      • 1.2.3 系统信息类
      • 1.2.4 exec
      • 1.2.5 其他方法
      • 1.2.6 注意事项
  • 二、基本使用
    • 2.1 获取当前虚拟机信息
    • 2.2 操作系统进程
    • 2.3 Process对象
  • 三、业务场景实战
    • 3.1 执行外部脚本
    • 3.2 动态加载类
  • 四、小结

一、快速入门

1.1 Runtime 介绍

  Java Runtime 类是 Java 标准库中的关键类之一,它提供了对当前Java虚拟机实例的访问和控制,允许程序动态地修改和管理运行时环境。每个Java应用程序都有一个Runtime类实例,使得程序能够与其运行的环境相连接。
  Runtime类所在包为java.lang包,因此在使用的时候不需要进行导包。并且Runtime类被public修饰了,因此该类是可以被继承的。

在这里插入图片描述

1.2 常用方法

  程序中一般不能显式的主动实例化一个Runtime实例,而是通过Runtime.getRuntime()来获取当前程序的Runtime实例。通过getRuntime()获取到当前程序的运行环境之后,就可以做很多事了,比如说调用运行环境,执行一些cmd任务,或者外部的脚本等。由于Runtime类封装了虚拟机进程,因此,在程序中通常会通过该类的实例对象来获取当前虚拟机的相关信息。其常用方法和功能如下表所示:

1.2.1 基本方法

方法描述
static Runtime getRuntime()获取当前Java应用程序相关的运行时对象

1.2.2 行为控制类

方法描述
void addShutdownHook(Thread hook)注册新的虚拟机来关闭挂钩
boolean removeShutdownHook(Thread hook)移除一个虚拟机关机任务,与addShutdownHook作用相反
void exit(int status)通过启动虚拟机的关闭序列,终止当前正在运行的Java虚拟机
void gc()调用该方法可以触发垃圾回收器的执行,以回收不再使用的对象占据的内存空间
System.gc()就是调用的Runtime的gc()函数
void halt(int status)强行终止目前正在运行的Java虚拟机

1.2.3 系统信息类

方法说明
int availableProcessors()向 Java 虚拟机返回可用处理器的数目
long freeMemory()返回当前Java虚拟机中的空闲内存量
long maxMemory()返回当前Java虚拟机可以使用的最大内存量,即堆的最大容量
long totalMemory()返回当前Java虚拟机当前已经使用的总内存量

注意:Runtime 类的 freeMemory、totalMemory、maxMemory三个方法反映的都是 Java 这个进程的内存情况,跟操作系统的内存根本没有关系。

1.2.4 exec

重载的exec()函数,可以执行指定的参数来达到执行cmd命令的目的。

方法说明
exec(String command)用于在操作系统中执行指定的命令,它创建一个新的进程并在其中执行给定的命令
exec(String[] cmdarray)在单独的进程中执行指定命令和变量
exec(String[] cmdarray,String[] envp)在指定环境的独立进程中执行指定命令和变量
exec(String[] cmdarray,String[] envp,File dir)在指定环境和工作目录的独立进程中执行指定的命令和变量
exec(String command,String[] envp)在指定环境的单独进程中执行指定的字符串命令
exec(String command,String[] envp,File dir)在有指定环境和工作目录的独立进程中执行指定的字符串命令

1.2.5 其他方法

方法说明
load(String filename)加载作为动态库的指定文件名
loadLibrary(String libname)加载具有指定库名的动态库
runFinalization()运行挂起finalization的所有对象的终止方法
traceInstructions(on)启用/禁用指令跟踪
traceMethodCalls(on)启用/禁用方法调用跟踪

1.2.6 注意事项

  这些方法允许Java应用程序与其运行时环境进行交互,获取内存使用情况、执行系统命令等操作。需要注意的是,在使用exec()方法执行系统命令时,可能需要处理输入流和输出流,以便与子进程进行通信,并正确处理可能的异常情况。在runtime执行大点的命令中,输入流和错误流会不断有流进入存储在JVM的缓冲区中,如果缓冲区的流不被读取被填满时,就会造成runtime的阻塞。所以在进行比如:大文件复制等的操作时,我们还需要不断的去读取JVM中的缓冲区的流,来防止Runtime的死锁阻塞。

二、基本使用

2.1 获取当前虚拟机信息

Runtime类可以获取当前Java虚拟机的处理器的个数、空闲内存量、最大可用内存量和内存总量的信息。

public static void main(String[] args) {
    // 获取当前系统的运行环境对象
    Runtime rt = Runtime.getRuntime();
	System.out.println("处理器的个数: " + rt.availableProcessors() + "个");
	System.out.println("空闲内存数量: " + rt.freeMemory() / 1024 / 1024 + "M");
	System.out.println("最大可用内存数量: " + rt.maxMemory() / 1024 / 1024 + "M");
	System.out.println("虚拟机中内存总量: " + rt.totalMemory() / 1024 / 1024 + "M");
}

由于每个人的机器配置不同,该示例的打印结果可能不同,另外空闲内存数、可用最大内存数和内存总量都是以字节为单位计算的,上述运行结果已经将字节换算成了兆(M)。

2.2 操作系统进程

  Runtime类中提供了一个exec()方法,该方法用于执行指定的字符串命令,从而实现和在命令行窗口中输入命令同样的效果。该方法返回一个代表进程的Process对象,可以通过该对象获取进程的输入流、输出流和出错流,并与进程进行交互。例如,通过运行“notepad.exe”命令打开一个Windows自带的记事本程序。程序运行后,会在Windows系统中产生一个新的进程notepad.exe,可以通过任务管理器进行观察。

public static void main(String[] args) throws IOException {
	// 创建Runtime实例对象
	Runtime rt = Runtime.getRuntime();
	// 调用exec()方法
	rt.exec("notepad.exe");
}

  Runtime 是 Java 提供的一个启动子进程来执行命令的方式,它提供了以下六个重载的 exec 方法,用于单独启动一个子进程来执行命令或调用程序。每一个方法最终都返回一个 Process 对象表示一个进程,从该对象中能够获取进程执行的退出状态码、标准输出流和标准错误流,进而获取进程执行的输出内容。

public Process exec(String command) throws IOException
public Process exec(String command, String[] envp) throws IOException
public Process exec(String command, String[] envp, File dir) throws IOException
public Process exec(String cmdarray[]) throws IOException
public Process exec(String[] cmdarray, String[] envp) throws IOException
public Process exec(String[] cmdarray, String[] envp, File dir) throws IOException

  其中,前五个方法都是间接调用最后一个方法,该方法有 3 个参数:

参数说明
cmdarray命令字符串数组
envp字符串数组(可以为空),表示命令执行过程中设置的环境变量
dir一个File对象(可以为空),表示命令执行的工作目录。
如果命令中有使用到类似于./的相对路径,则该相对路径就是基于dir的

这里需要特殊说明一下,单字符串命令和命令数组的区别,总结如下:

  • 如果执行的命令的参数中包含空格一定要使用 exec(String[] cmdarray, String[] envp, File dir),否则将导致命令执行失败。
  • 如果执行的命令的参数中没有空格不会导致参数分裂,则两个方法都一样

2.3 Process对象

  查阅API文档会发现,Runtime类的exec()方法返回一个Process对象,该对象就是exec()所生成的新进程,通过该对象可以对产生的新进程进行管理,如关闭此进程只需任务管理器中终止记事本进程的命令即可。具有代码如下所示:

public static void main(String[] args) {
	try {
		Process process = Runtime.getRuntime().exec("notepad.exe");

		// 休眠3秒
		Thread.sleep(3000);

		// 执行任务管理器中终止记事本进程的命令
		Runtime.getRuntime().exec("taskkill /F /IM notepad.exe");
	} catch (IOException e) {
		e.printStackTrace();
	} catch (InterruptedException e) {
		e.printStackTrace();
	}
}

Process的几种方法

方法说明
destroy()杀掉子进程
exitValue()返回子进程的出口值,值0表示正常终止
getErrorStream()获取子进程的错误流
getInputStream()获取子进程的输入流
getOutputStream()获取子进程的输出流
waitFor()导致当前线程等待,如有必要,一直要等到由该Process对象表示的进程已经终止。
如果已终止该子进程,此方法立即返回。
如果没有终止该子进程,调用的线程将被阻塞,直到退出子进程,根据惯例,0表示正常终止

三、业务场景实战

3.1 执行外部脚本

下面是一个演示如何使用 Runtime 类来执行外部脚本的 Java 实例程序:

import java.io.BufferedReader;
import java.io.IOException;
import java.io.InputStreamReader;

public class ExecuteScriptExample {
    public static void main(String[] args) {
        Runtime runtime = Runtime.getRuntime();
        try {
            // 使用 runtime.exec() 方法执行外部脚本
            Process process = runtime.exec("python script.py");

            // 获取外部脚本的输入流,并创建 BufferedReader 对象用于读取输出结果
            BufferedReader reader = new BufferedReader(new InputStreamReader(process.getInputStream()));
            
            String line;
            while ((line = reader.readLine()) != null) {
                // 处理外部脚本输出的每一行
                System.out.println(line);
            }

            // 等待外部进程结束并获取退出值
            int exitCode = process.waitFor();
            
            if (exitCode == 0) {
                // 外部脚本执行成功
                System.out.println("External script executed successfully.");
            } else {
                // 外部脚本执行失败
                System.err.println("External script execution failed. Exit code: " + exitCode);
            }
        } catch (IOException | InterruptedException e) {
            // 处理异常
            e.printStackTrace();
        }
    }
}

  这个实例展示了如何在 Java 中使用 Runtime 类来执行外部脚本,并处理输出结果和异常情况。注意,使用 runtime.exec() 执行外部命令需要谨慎处理,特别是针对从用户输入或不受信任的源代码中派生的命令。建议对脚本及其参数进行适当的验证和限制,以确保安全性。

3.2 动态加载类

下面是一个演示如何使用 Runtime 类结合反射机制来动态加载类的Java实例程序:

import java.lang.reflect.Method;

public class DynamicClassLoadingExample {
    public static void main(String[] args) {
        try {
            // 创建Runtime对象
            Runtime runtime = Runtime.getRuntime();

            // 加载需要动态加载的类的全限定名
            String className = "com.example.MyClass";

            // 使用ClassLoader动态加载类
            Class<?> dynamicClass = runtime.getClass().getClassLoader().loadClass(className);

            // 创建类的实例
            Object instance = dynamicClass.newInstance();

            // 调用类中的方法
            Method method = dynamicClass.getDeclaredMethod("doSomething");
            method.invoke(instance);
        } catch (ClassNotFoundException e) {
            // 处理类未找到异常
            e.printStackTrace();
        } catch (InstantiationException | IllegalAccessException | NoSuchMethodException | InvocationTargetException e) {
            // 处理其他异常
            e.printStackTrace();
        }
    }
}

  这个实例演示了如何使用 Runtime 类动态加载类,并调用其中的方法。需要注意,动态加载类在某些场景下是有用的,但也应谨慎使用。合理地处理异常情况以及对类名、方法等进行适当的验证和限制是非常重要的。

四、小结

  在学习面向对象概念时曾经强调过一个概念,一个类中至少会存在一个构造方法, 如果本类没有定义任何构造方法,那么会自动生成一个无参的构造方法。 但是当打开 Runtime类时会发现一个问题,在这个类中并没有构造方法的定义说明,可是这个类的构造方法却是真实存在的,因为其在声明时对构造方法进行了封装 所以Runtime类是一个典型的单例设计模式。
  Java Runtime 类作为Java虚拟机的实例,对于动态地控制运行时环境至关重要。通过提供各种功能和方法,例如执行外部命令、管理内存和垃圾回收,以及动态加载和卸载类,Runtime 类使得Java程序能够更加灵活地与底层系统进行交互。然而,开发人员需要注意安全性、性能优化及平台依赖性等方面,以确保代码的可靠性和效率。熟练使用 Runtime 类,并根据具体需求进行合理的优化,将有助于实现更强大和高效的Java应用程序。

本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若转载,请注明出处:http://www.coloradmin.cn/o/1054259.html

如若内容造成侵权/违法违规/事实不符,请联系多彩编程网进行投诉反馈,一经查实,立即删除!

相关文章

《数据结构、算法与应用C++语言描述》-栈的应用-迷宫老鼠问题

迷宫老鼠 问题描述 迷宫&#xff08;如图 8-9 所示&#xff09;是一个矩形区域&#xff0c;有一个入口和一个出口。迷宫内部包含不能穿越的墙壁或障碍物。这些障碍物沿着行和列放置&#xff0c;与迷宫的边界平行。迷宫的入口在左上角&#xff0c;出口在右下角。 假定用 nxm 的…

【Java每日一题】——第十六题:将数组元素逆序并遍历输出。(2023.09.30)

&#x1f578;️Hollow&#xff0c;各位小伙伴&#xff0c;今天我们要做的是第十五题。 &#x1f3af;问题&#xff1a; 设有数组如下&#xff1a;int[] arr{11,34,47,19,5,87,63,88}; 测试结果如下&#xff1a; &#x1f3af; 答案&#xff1a; int a[]new int [10];Random …

《三国志》游戏的MySQL数据设计与管理

在任何成功的游戏背后,都有一个精心设计和管理的数据系统。这不仅决定了游戏的运行效率,还直接影响到玩家的游戏体验。 本文将深入探讨著名游戏《三国志》中的数据设计和管理。本文将讲解游戏中核心的数据元素、数据管理方法,以及开发团队在数据方面所做的工作。 文章目录 …

【C语言次列车ing】No.1站---C语言入门

文章目录 前言一、什么是C语言二、第一个C语言程序三、数据类型四、变量、常量五、字符串转义字符注释 前言 &#x1f467;个人主页&#xff1a;小沈YO. &#x1f61a;小编介绍&#xff1a;欢迎来到我的乱七八糟小星球&#x1f31d; &#x1f4cb;专栏&#xff1a;C语言次列车i…

考研王道强化阶段(二轮复习)“算法题”备考打卡表 记录

问题&#xff1a;做408真题_2010_42题&#xff0c;即王道书 2.2.3_大题_10 思路&#xff1a; 回头补 代码&#xff1a; int moveL(SqlList &L,SqlList &S,int p) {// 健壮性表达if( L.len 0 ){return 0;}// 调用另外一个顺序表存储pos前面的元素for( int i0;i<p;…

【模型压缩】模型剪枝模块

模型剪枝模块 最基本的基于阈值策略 基于分布来选择阈值 假定权重是符合一个正太分布正态分布有68% 小于标准差 将标准差作为阈值卷积层的敏感度要比全连接层更大&#xff1a;导致有些层over-pruning 有些层 under-pruning 设置预期的稀疏率 权重值按照绝对值进行排序从最小…

字符串函数与内存函数讲解

文章目录 前言一、字符串函数1.求字符串长度strlen 2.长度不受限制的字符串函数(1)strcpy(2)strcat(3)strcmp 3.长度受限制的字符串函数(1)strncpy(2)strncat(3)strncmp 4.字符串查找(1)strstr(2)strtok 5.错误信息报告(1)strerror(2)perror 二、内存函数1.memcpy2.memmove3.me…

山西电力市场日前价格预测【2023-10-02】

日前价格预测 预测说明&#xff1a; 如上图所示&#xff0c;预测明日&#xff08;2023-10-02&#xff09;山西电力市场全天平均日前电价为355.35元/MWh。其中&#xff0c;最高日前电价为521.18元/MWh&#xff0c;预计出现在18: 45。最低日前电价为309.36元/MWh&#xff0c;预计…

【C语言深入理解指针(2)】

1. 数组名的理解 在上⼀个博客我们在使⽤指针访问数组的内容时&#xff0c;有这样的代码&#xff1a; int arr[10] {1,2,3,4,5,6,7,8,9,10}; int *p &arr[0];这⾥我们使⽤ &arr[0] 的⽅式拿到了数组第⼀个元素的地址&#xff0c;但是其实数组名本来就是地址&#x…

Windows驱动反调试的一种手段

Windows驱动反调试的一种手段 今天要介绍的是eprocess的0xbc位置 0x0bc DebugPort : Ptr32 Void DebugPort是在用windowsapi调试方式时候所使用的数据结构指针&#xff0c;那么如果我们能够循环清空这个值的话&#xff0c;就可以做到大部分windows调试api都无法正确调试进程 …

机器学习算法基础--聚类问题的评价指标

1.聚类问题指标评价的意义 聚类算法是非监督学习最常用的一种方法&#xff0c;性能度量是衡量学习模型优劣的指标&#xff0c;也可作为优化学习模型的目标函数。聚类性能度量根据训练数据是否包含标记数据分为两类&#xff0c;一类是将聚类结果与标记数据进行比较&#xff0c;称…

【Axure】常见元件、常用交互效果

产品结构图 以微信为例&#xff0c;根据页面层级制作 动态面板 动态面板的作用&#xff1a;动态面板是一个可视区域&#xff0c;如果要把控件放进去&#xff0c;要全部放进去&#xff0c;放多少显示多少 文本框 隐藏边框方法&#xff1a;先拉一个矩形&#xff0c;去掉部分…

uniapp项目实践总结(二十五)苹果 ios 平台 APP 打包教程

导语:当你的应用程序开发完成后,在上架 ios 应用商店之前,需要进行打包操作,下面就简单介绍一下打包方法。 目录 准备工作注册账号生成证书打包配置准备工作 在打包之前,请保证你的 uniapp 应用程序编译到 ios 模拟器或者是真机调试基座环境下是可以正常运行的,苹果打包…

记录一次阿里云服务器ECS上启动的portainer无法访问的问题

如下图&#xff0c;在阿里云ECS服务器上安装并启动了portainer&#xff0c;但是在自己电脑上访问不了远程的portainer。 最后发现是要在网络安全组里开放9000端口号&#xff0c;具体操作如下&#xff1a; 在云服务器管理控制台点击左侧菜单中的网络与安全-安全组&#xff0c;然…

国庆day2---select实现服务器并发

select.c&#xff1a; #include <myhead.h>#define ERR_MSG(msg) do{\fprintf(stderr,"__%d__:",__LINE__);\perror(msg);\ }while(0)#define IP "192.168.1.3" #define PORT 8888int main(int argc, const char *argv[]) {//创建报式套接字socketi…

Java笔记五(数组)

目录 数组 数组声明创建 数组初始化的三种初始化类型&#xff1a; 静态初始化 动态初始化 数组的默认初始化 数组的四个基本特点 数组边界 数组的使用 示例一&#xff1a;计算所有的元素和以及查找最大元素 示例二&#xff1a;For-Each循环 示例三&#xff1a;数组作…

[NOIP2011 提高组] 选择客栈

[NOIP2011 提高组] 选择客栈 题目描述 丽江河边有 n n n 家很有特色的客栈&#xff0c;客栈按照其位置顺序从 1 1 1 到 n n n 编号。每家客栈都按照某一种色调进行装饰&#xff08;总共 k k k 种&#xff0c;用整数 0 ∼ k − 1 0 \sim k-1 0∼k−1 表示&#xff09;&am…

【论文笔记】SVDM: Single-View Diffusion Model for Pseudo-Stereo 3D Object Detection

原文链接&#xff1a;https://arxiv.org/abs/2307.02270 1. 引言 目前的从单目相机生成伪传感器表达的方法依赖预训练的深度估计网络。这些方法需要深度标签来训练深度估计网络&#xff0c;且伪立体方法通过图像正向变形合成立体图像&#xff0c;会导致遮挡区域的像素伪影、扭…

初识Java 12-1 流

目录 Java 8对流的支持 流的创建 随机数流 int类型的区间范围 generate() iterate() 流生成器 Arrays 正则表达式 本笔记参考自&#xff1a; 《On Java 中文版》 ||| 流的概念&#xff1a;流是一个与任何特定的存储机制都没有关系的元素序列。 流与对象的成批处理有关…

CSP-J第二轮试题-2021年-3题

文章目录 参考&#xff1a;总结 [CSP-J 2021] 网络连接题目描述输入格式输出格式样例 #1样例输入 #1样例输出 #1 样例 #2样例输入 #2样例输出 #2 样例 #3样例输入 #3样例输出 #3 样例 #4样例输入 #4样例输出 #4 提示答案1答案2 现场真题注意事项 参考&#xff1a; https://www…