[Linux] 一个Linux底层工具类

自己常用的Linux工具类,包含功能:

  1. 获取进程PID
  2. 获取服务器CPU占用率
  3. 获取服务器内存实际占用率
  4. 获取服务器磁盘IO

 

package ebda.platform.util;

import java.io.BufferedReader;
import java.io.File;
import java.io.FileInputStream;
import java.io.IOException;
import java.io.InputStreamReader;
import java.lang.management.ManagementFactory;
import java.net.InetAddress;
import java.util.StringTokenizer;

/**
 * Linux底层工具类
 * @author ebda.zh
 */
@SuppressWarnings("restriction")
public class LinuxUtil {
	
	//返回主机名
	public static String getHostName() throws Exception{
		try{
			InetAddress netAddress = InetAddress.getLocalHost();
			String hostName = netAddress.getHostName();
			return hostName;
		}catch(Exception e){
			e.printStackTrace();
			throw(e);
		}
		//return null;
	}
	
	
	/**
	 * 获取当前PID值
	 * @return
	 */
	public static  String getPID_current(){
		String name = ManagementFactory.getRuntimeMXBean().getName();    
		System.out.println(name);    
		// get pid    
		String pid = name.split("@")[0];    
		System.out.println("Pid is:" + pid);   
		
		return pid;
	} 
	
	
	public static  String getPID(String keyWords) throws Exception{
		Process process;
		String PID="";
		try {
			/** 示例
			 *  ps -ef|grep ebda.sh |grep $user|grep -v "grep"|grep -v "vi"|grep -v "view"
			 */
			process = Runtime.getRuntime().exec(new   String[]{"/bin/sh","-c","ps -ef | grep "+  System.getProperty("user.name") + " | grep -v \"grep\"|grep -v \"vi\"|grep -v \"view\"|grep " + keyWords});
			BufferedReader br = new BufferedReader(new InputStreamReader(process.getInputStream()));
			//info = br.readLine();
			/**示例,获取的进程信息如下
			hadoop    7153   65211  0 01:43 ?        00:00:00 /usr/local/java/jdk1.7.0_71/bin/java -Dfile.encoding=UTF-8 -classpath /home/hadoop/EBDA_wk/ebda_main/bin:/home/hadoop/EBDA_wk/ebda_main/lib/aopalliance.jar:/home/hadoop/EBDA_wk/ebda_main/lib/aspectjweaver.jar:/home/hadoop/EBDA_wk/ebda_main/lib/c3p0-0.9.1.2.jar:/home/hadoop/EBDA_wk/ebda_main/lib/commons-compress-1.9.jar:/home/hadoop/EBDA_wk/ebda_main/lib/commons-lang-2.3.jar:/home/hadoop/EBDA_wk/ebda_main/lib/commons-logging-1.1.1.jar:/home/hadoop/EBDA_wk/ebda_main/lib/jdom.jar:/home/hadoop/EBDA_wk/ebda_main/lib/log4j.jar:/home/hadoop/EBDA_wk/ebda_main/lib/ojdbc14.jar:/home/hadoop/EBDA_wk/ebda_main/lib/postgresql-9.3-1102.jdbc4.jar:/home/hadoop/EBDA_wk/ebda_main/lib/quartz-1.8.6.jar:/home/hadoop/EBDA_wk/ebda_main/lib/slf4j-api-1.6.1.jar:/home/hadoop/EBDA_wk/ebda_main/lib/slf4j-log4j12-1.6.1.jar:/home/hadoop/EBDA_wk/ebda_main/lib/spring-aop-3.2.5.RELEASE.jar:/home/hadoop/EBDA_wk/ebda_main/lib/spring-beans-3.2.5.RELEASE.jar:/home/hadoop/EBDA_wk/ebda_main/lib/spring-context-3.2.5.RELEASE.jar:/home/hadoop/EBDA_wk/ebda_main/lib/spring-context-support-3.2.5.RELEASE.jar:/home/hadoop/EBDA_wk/ebda_main/lib/spring-core-3.2.5.RELEASE.jar:/home/hadoop/EBDA_wk/ebda_main/lib/spring-expression-3.2.5.RELEASE.jar:/home/hadoop/EBDA_wk/ebda_main/lib/spring-jdbc-3.2.5.RELEASE.jar:/home/hadoop/EBDA_wk/ebda_main/lib/spring-tx-3.2.5.RELEASE.jar:/home/hadoop/EBDA_wk/ebda_main/lib/xerces-2.6.2.jar ebda.platform.main.Main
			用户		  进程ID 
			 */
			PID = br.readLine().split("\\s+")[1];
			/**示例,截取后获得PID
				7153
			 */
		} catch (IOException e) {
			// TODO Auto-generated catch block
			e.printStackTrace();
			throw(e);
		}

		return PID;
	} 
	
	
	
	/**[About Linux Memory]
	 * 
	 * linux下在终端环境下可以使用free命令看到系统实际使用内存的情况,一般用free -m方式查看内存占用情况(兆为单位)。而系统实际可用内存是不是free部分呢,不是的,系统实际内存占用以及可用内存有如下几个加减法:

used=total-free 即 total=used+free
实际内存占用:used-buffers-cached 即 total-free-buffers-cached
实际可用内存:buffers+cached+free
					total  	used  	free	shared 	 buffers 	cached
Mem:            	128    	119  	 8 		 0   	 1  	   22
-/+ buffers/cache: 	95  	32
swap:          		255  	0 		 255

 

第1行Mem数据:

total 内存总数: 128
used 已经使用的内存数: 119
free 空闲的内存数: 8
shared 当前已经废弃不用,总是0
buffers Buffer Cache内存数: 1
cached Page Cache内存数: 22
第2行-/+ buffers/cache:

-buffers/cache 的内存数:95 (等于第1行的 used - buffers - cached)
+buffers/cache 的内存数: 32 (等于第1行的 free + buffers + cached)
可见-buffers/cache反映的是被程序实实在在吃掉的内存,而+buffers/cache反映的是可以挪用的内存总数。

第三行数据是交换分区SWAP的,也就是我们通常所说的虚拟内存。

为了提高磁盘存取效率, Linux做了一些精心的设计, 除了对dentry进行缓存(用于VFS,加速文件路径名到inode的转换), 还采取了两种主要Cache方式:Buffer Cache和Page Cache。前者针对磁盘块的读写,后者针对文件inode的读写。这些Cache有效缩短了 I/O系统调用(比如read,write,getdents)的时间。

感兴趣的可以进一步参考文件/proc/meminfo,free命令就是根据它的信息生成的。free命令的源码可从procps-xxx-.src.rpm获取,xxx为版本号,比如procps-3.2.3-5.3.src.rpm。
	 */
	
	/**
	 * 
	 * @return Memory Usage Percent : [[[[[[[[[[buffers+cached+free/memALL]]]]]]]]]]
	 * @throws IOException
	 * @throws InterruptedException
	 */
    public static float getMemPercent() throws IOException, InterruptedException
    {
		long[] memInfo = LinuxUtil.getMemInfo();
		return ( (float)memInfo[1] +  (float)memInfo[2] + (float)memInfo[3])/ (float)memInfo[0];
    }
	
	/**
	    * get memory by used info
	    *
	    * @return int[] result
	    * result.length==4;int[0]=MemTotal;int[1]=MemFree;int[2]=SwapTotal;int[3]=SwapFree;
	    * @throws IOException
	    * @throws InterruptedException
	    */
    public static long[] getMemInfo() throws IOException, InterruptedException
    {
        File file = new File("/proc/meminfo");
        BufferedReader br = new BufferedReader(new InputStreamReader(
        new FileInputStream(file)));
        long[] result = new long[4];
        String str = null;
        StringTokenizer token = null;
        

        while((str = br.readLine()) != null)
        {	
            token = new StringTokenizer(str);
            if(!token.hasMoreTokens())
            continue;
            str = token.nextToken();
            if(!token.hasMoreTokens())
            continue;
/**
 * used=total-free 即 total=used+free
实际内存占用:used-buffers-cached 即 total-free-buffers-cached
实际可用内存:buffers+cached+free
					total  	used  	free	shared 	 buffers 	cached
Mem:            	128    	119  	 8 		 0   	 1  	   22
-/+ buffers/cache: 	95  	32
swap:          		255  	0 		 255
					total  	used  	free	shared 	 buffers 	cached
Mem:            MemTotal    119  	 8 		 0   	 1  	   22
-/+ buffers/cache: 	95  	32
swap:          		255  	0 		 255
 */
            if(str.equalsIgnoreCase("MemTotal:"))
            result[0] = Long.parseLong(token.nextToken());
            else if(str.equalsIgnoreCase("MemFree:"))		//MemFree
            result[1] = Long.parseLong(token.nextToken());
            else if(str.equalsIgnoreCase("Buffers:"))       //Buffers
            result[2] = Long.parseLong(token.nextToken());
            else if(str.equalsIgnoreCase("Cached:"))		 //Cached
            result[3] = Long.parseLong(token.nextToken());
            /*
            else if(str.equalsIgnoreCase("SwapCached:"))
            result[4] = Integer.parseInt(token.nextToken());
            else if(str.equalsIgnoreCase("Active:"))
            result[5] = Integer.parseInt(token.nextToken());
            else if(str.equalsIgnoreCase("Inactive:"))
            result[6] = Integer.parseInt(token.nextToken());
            else if(str.equalsIgnoreCase("SwapTotal:"))
            result[7] = Integer.parseInt(token.nextToken());
            else if(str.equalsIgnoreCase("SwapFree:"))
            result[8] = Integer.parseInt(token.nextToken());
            */
        }
        return result;
    }
	    /**
	    * get cpu by used info
	    *
	    * @return float efficiency
	    * @throws IOException
	    * @throws InterruptedException
	    */
	    public static float getCPUPercent() throws IOException, InterruptedException
	    {
		    File file = new File("/proc/stat");
		    BufferedReader br = new BufferedReader(new InputStreamReader(
		    new FileInputStream(file)));
		    StringTokenizer token = new StringTokenizer(br.readLine());
		    token.nextToken();
		    long user1 = Long.parseLong(token.nextToken());
		    long nice1 = Long.parseLong(token.nextToken());
		    long sys1 = Long.parseLong(token.nextToken());
		    long idle1 = Long.parseLong(token.nextToken());
		    Thread.sleep(1000);
		    br = new BufferedReader(
		    new InputStreamReader(new FileInputStream(file)));
		    token = new StringTokenizer(br.readLine());
		    token.nextToken();
		    long user2 = Long.parseLong(token.nextToken());
		    long nice2 = Long.parseLong(token.nextToken());
		    long sys2 = Long.parseLong(token.nextToken());
		    long idle2 = Long.parseLong(token.nextToken());
		    return (float)((user2 + sys2 + nice2) - (user1 + sys1 + nice1)) / (float)((user2 + nice2 + sys2 + idle2) - (user1 + nice1 + sys1 + idle1));
	    }
	
	

}

分类上一篇:无,已是最新文章    分类下一篇:

Leave a Reply