利用 Runtime 监控 Java 系统资源

利用 Runtime 监控 Java 系统资源

这些日子要用爪哇语言(Java)做内存数据中心。于是把用 Java 监控运行环境硬件资源的内容复习了一下。爪哇类库提供了 java.util.Runtim 类,主要负责调用爪哇虚拟机(JavaVM)外部的基层操作系统功能、处理基于一种叫钩子的原理的程序、获取系统资源信息以及控制调试信息生成。本文单独利用其获取系统资源信息的功能。

java.util.Runtim 类具有以下几个方法和获取系统资源信息有关。以下代码可不是简简单单从标准类库里边复制出来的哦。全球目前独此一份。

/** */ /**
 * 返回爪哇(Java)虚拟机可用线程数。
 *
 * <p>该值在特定的虚拟机调用期间可能发生更改。因此,对可用处理器数目很敏感的
 * 应用程序应该不定期地轮询该属性,并相应地调整其资源用法。</p>
 *
 * 
@return  虚拟机可用的最大处理器数目;从不小于 1
 * 
@since 1.4
 
*/

public   native   int  availableProcessors();

/** */ /**
 * 返回爪哇(Java)虚拟机中的空闲内存量。调用 <code>gc</code> 方法可能导致
 * <code>freeMemory</code> 返回值的增加。
 *
 * 
@return  供将来分配对象使用的当前可用内存的近似总量,以字节为单位。
 
*/

public   native   long  freeMemory();

/** */ /**
 * 返回爪哇(Java)虚拟机中的内存总量。此方法返回的值可能随时间的推移而变化,这
 * 取决于主机环境。
 * <p>
 * 注意,保存一个给定类型的对象所需的内存量可能取决于实现方式。
 *
 * 
@return  目前为当前和后续对象提供的内存总量,以字节为单位。
 
*/

public   native   long  totalMemory();            //                                  //

/** */ /**
 * 返回爪哇(Java)虚拟机能够尝试使用的最大内存量。如果内存本身没有限制,则
 * 返回值 {
@link java.lang.Long#MAX_VALUE} 。 </p>
 *
 * 
@return  虚拟机能够尝试使用的最大内存量,以字节为单位。
 * 
@since 1.4
 
*/

public   native   long  maxMemory();

/** */ /**
 * 运行垃圾回收器。
 * 调用此方法意味着爪哇(Java)虚拟机做了一些努力来回收未用对象,以便能够快速地
 * 重用这些对象当前占用的内存。当控制从方法调用中返回时,虚拟机已经尽最大努力回收
 * 了所有丢弃的对象。
 * <p>
 * 名称 <code>gc</code> 代表“垃圾回收器”。虚拟机根据需要在单独的线程中自动执行
 * 回收过程,甚至不用显式调用 <code>gc</code> 方法。
 * <p>
 * 方法 {
@link System#gc()} 是调用此方法的一种传统而便捷的方式
 
*/

public   native   void  gc();

 








我们可以看到这些都是本地方法。这意味着将 Runtime 对象远程传递之后,将不能得到正确执行结果。
这些方法用起来都很简单,文档注释也写得比较明白。
在高可用数据中心中,我认为应该根据可用 CPU 线数决定程序开启的线程数 。此线程数为 CPU 可用线数的某倍数。此倍数应通过实际经验所得。然后程序通过监控 CPU 可用线数,来控制线程池保留数量。
内存的控制,我想应该是在内存超出警戒线时发出警报 ,以向运营人员申请增加内存数据中心服务器。同时,应该在内存过满之前,由程序执行垃圾回收 ,以消除并无引用的老生代对象。
如果各位有对内存数据中心的想法、建议或者质疑,欢迎来一起讨论。
下边是我编写的一个系统资源测试程序。程序里边使用了 Runtime 类关于系统资源的所有方法。

package  cn.spads.test.grammar;

import  java.util.LinkedList;
import  java.util.Random;

/** */ /**
 * 本类用于示范使用 Runtime 检查系统运行情况。
 * 将 Runtime 作为可变成员,是为多系统公用检查预留的设计。
 * 
@author    Shane Loo Li
 
*/

public   class  PerformanceMonitor
{
    
/** *//**
     * 此量控制程序运行时间。此值越大,此演示程序运行时间越长。
     
*/

    
static public int runLoopTimes = 55;

    
/** *//**
     * 此为每次检测间隔的时间片数。此值越大,间隔时间越长。
     
*/

    
static public int waitTime = 1500000;

    
static public void main(String[] arguments) throws Exception
    
{
        Runtime context 
= Runtime.getRuntime();
        
final PerformanceMonitor monitor = new PerformanceMonitor(context);
        
final LinkedList<String> pretendedMemory = new LinkedList<String>();
        
new Thread(
                
new Runnable()
                
{
                    
public void run()
                    
{
                        
for (int j = -1++!= runLoopTimes; )
                        
{
                            
// 检查系统情况
                            monitor.checkAll();

                            
// 每次检查运行情况之后,都会休息 1000 个时间片
                            for (int i = -1++!= waitTime; ) Thread.yield();

                            
// 每次检查之后,会制造一些对象,记录其中一部分,并删除些老对象
                            for (int i = -1++!= 20000; )
                            
{
                                StringBuilder builder 
= new StringBuilder();
                                Random ran 
= new Random();
                                
for (int index = -1++index != 100; )
                                    builder.append((
char) (ran.nextInt(26+ 64));
                                String garbage 
= new String(builder.toString());
                                garbage 
= garbage.substring(garbage.length());
                                pretendedMemory.add(builder.toString());
                            }

                            
int deleteCount = new Random().nextInt(15000);
                            
for (int i = -1++!= deleteCount; )
                                pretendedMemory.removeFirst();

                            System.out.println(
"-----------");
                        }

                    }

                }

            ).start();
    }


    
private Runtime context;
    
private double maxFreeMemory;

    
private long lastFreeMemory;
    
private long lastTotalMemory;
    
private long lastMaxMemory;

    
private double lastMemoryRate;

    
public PerformanceMonitor(Runtime context)
    
{
        
this.context = context;
    }


    
public void checkAll()
    
{
        
this.monitorMemory();
        
this.monitorCpu();
    }

    
/** *//**
     * 本方法比较当前空余内存与历史记录最大空余内存的关系。若空余内存过小,则执行垃圾回收。
     
*/

    
public void monitorMemory()
    
{
        
// 求空余内存,并计算空余内存比起最大空余内存的比例
        long freeMemory = this.context.freeMemory();
        
if (freeMemory > this.maxFreeMemory)
            
this.maxFreeMemory = Long.valueOf(freeMemory).doubleValue();
        
double memoryRate = freeMemory / this.maxFreeMemory;
        System.out.println(
"There are " + memoryRate * 100 + "% free memory.");

        
// 如果内存空余率在变小,则一切正常;否则需要报告内存变化情况
        if (memoryRate >= this.lastMemoryRate) this.reportMemoryChange();

        
// 如果内存空余率很低,则执行内存回收
        if (freeMemory / this.maxFreeMemory < 0.3)
        
{
            System.out.print(
"System will start memory Garbage Collection.");
            System.out.println(
" Now we have " + freeMemory / 1000 + " KB free memory.");
            
this.context.gc();
            System.out.println(
"After the Garbage Collection, we have "
                    
+ this.context.freeMemory() / 1000 + " KB free memory.");
        }


        
// 记录内存信息
        this.recordMemoryInfo(memoryRate);
    }


    
/** *//**
     * 报告内存变化情况
     
*/

    
private void reportMemoryChange()
    
{
        System.out.print(
"Last freeMemory = " + this.lastFreeMemory / 1000 + " KB,");
        System.out.println(
" now it is " + this.context.freeMemory() / 1000 + " KB.");
        System.out.print(
"Last totalMemory = " + this.lastTotalMemory / 1000 + " KB,");
        System.out.println(
" now it is " + this.context.totalMemory() / 1000 + " KB.");
        System.out.print(
"Last maxMemory = " + this.lastMaxMemory / 1000 + " KB,");
        System.out.println(
" now it is " + this.context.maxMemory() / 1000 + " KB.");
    }


    
/** *//**
     * 记录本次内存信息。
     
*/

    
private void recordMemoryInfo(double memoryRate)
    
{
        
this.lastFreeMemory = this.context.freeMemory();
        
this.lastMaxMemory = this.context.maxMemory();
        
this.lastTotalMemory = this.context.totalMemory();
        
this.lastMemoryRate = memoryRate;
    }


    
/** *//**
     * 监测 CPU 的方法。
     
*/

    
public void monitorCpu()
    
{
        
int cpuCount = this.context.availableProcessors();
        
if (cpuCount > 1) System.out.println("CPU have " + cpuCount + " processors.");
    }

}





我运行这段程序,得到结果报告。通过观察结果报告,我得到了一些新结论。
首先, maxMemory 在一台机器只运行一个爪哇(Java)虚拟机的前提下,一般来说并不会变动。
其次,新生代内存会很快地自动回收,这体现在 freeMemory 总是不断少量自动增加上。
最后,爪哇(Java)虚拟机会在内存不足时,自己申请新的内存。这个内存空间也能够根据报告大概看出一点原则:既不是完全通过可用内存比例,也不是完全通过可用内存数量。

我自己运行的报告附在下边

There are  100.0 %  free memory.
Last freeMemory 
=   0  KB, now it is  124371  KB.
Last totalMemory 
=   0  KB, now it is  126353  KB.
Last maxMemory 
=   0  KB, now it is  1875378  KB.
CPU have 
8  processors.
-----------
There are 
79.91675736339026 %  free memory.
CPU have 
8  processors.
-----------
There are 
82.1353751773145 %  free memory.
Last freeMemory 
=   99921  KB, now it is  102695  KB.
Last totalMemory 
=   126353  KB, now it is  126353  KB.
Last maxMemory 
=   1875378  KB, now it is  1875378  KB.
CPU have 
8  processors.
-----------
There are 
100.0 %  free memory.
Last freeMemory 
=   102695  KB, now it is  140522  KB.
Last totalMemory 
=   126353  KB, now it is  159383  KB.
Last maxMemory 
=   1875378  KB, now it is  1875378  KB.
CPU have 
8  processors.
-----------
There are 
82.4930651724349 %  free memory.
CPU have 
8  processors.
-----------
There are 
65.90519105111919 %  free memory.
CPU have 
8  processors.
-----------
There are 
88.50612783993465 %  free memory.
Last freeMemory 
=   92611  KB, now it is  124371  KB.
Last totalMemory 
=   159383  KB, now it is  159383  KB.
Last maxMemory 
=   1875378  KB, now it is  1875378  KB.
CPU have 
8  processors.
-----------
There are 
71.68576727159902 %  free memory.
CPU have 
8  processors.
-----------
There are 
54.86540670326339 %  free memory.
CPU have 
8  processors.
-----------
There are 
100.0 %  free memory.
Last freeMemory 
=   77098  KB, now it is  172330  KB.
Last totalMemory 
=   159383  KB, now it is  225443  KB.
Last maxMemory 
=   1875378  KB, now it is  1875378  KB.
CPU have 
8  processors.
-----------
There are 
86.18976806966614 %  free memory.
CPU have 
8  processors.
-----------
There are 
72.37916940114857 %  free memory.
CPU have 
8  processors.
-----------
There are 
58.56890497502629 %  free memory.
CPU have 
8  processors.
-----------
There are 
46.292794574206056 %  free memory.
CPU have 
8  processors.
-----------
There are 
92.98754812452182 %  free memory.
Last freeMemory 
=   79776  KB, now it is  160245  KB.
Last totalMemory 
=   225443  KB, now it is  225443  KB.
Last maxMemory 
=   1875378  KB, now it is  1875378  KB.
CPU have 
8  processors.
-----------
There are 
79.17694945600425 %  free memory.
CPU have 
8  processors.
-----------
There are 
65.36668502988196 %  free memory.
CPU have 
8  processors.
-----------
There are 
51.556035296554015 %  free memory.
CPU have 
8  processors.
-----------
There are 
37.745845146519564 %  free memory.
CPU have 
8  processors.
-----------
There are 
23.935246478001996 %  free memory.
System will start memory Garbage Collection. Now we have 
41247  KB free memory.
After the Garbage Collection, we have 
312897  KB free memory.
CPU have 
8  processors.
-----------
There are 
100.0 %  free memory.
Last freeMemory 
=   312897  KB, now it is  292267  KB.
Last totalMemory 
=   380108  KB, now it is  380108  KB.
Last maxMemory 
=   1875378  KB, now it is  1875378  KB.
CPU have 
8  processors.
-----------
There are 
91.1770148111291 %  free memory.
CPU have 
8  processors.
-----------
There are 
84.11856206174096 %  free memory.
CPU have 
8  processors.
-----------
There are 
75.29548107031924 %  free memory.
CPU have 
8  processors.
-----------
There are 
68.2370940141088 %  free memory.
CPU have 
8  processors.
-----------
There are 
59.414100613590705 %  free memory.
CPU have 
8  processors.
-----------
There are 
52.35564786420257 %  free memory.
CPU have 
8  processors.
-----------
There are 
43.53256687278083 %  free memory.
CPU have 
8  processors.
-----------
There are 
34.70958168390994 %  free memory.
CPU have 
8  processors.
-----------
There are 
27.6511289345218 %  free memory.
System will start memory Garbage Collection. Now we have 
80815  KB free memory.
After the Garbage Collection, we have 
281843  KB free memory.
CPU have 
8  processors.
-----------
There are 
89.37604181852511 %  free memory.
Last freeMemory 
=   281843  KB, now it is  261217  KB.
Last totalMemory 
=   380108  KB, now it is  380108  KB.
Last maxMemory 
=   1875378  KB, now it is  1875378  KB.
CPU have 
8  processors.
-----------
There are 
80.55442250030752 %  free memory.
CPU have 
8  processors.
-----------
There are 
73.49712485596086 %  free memory.
CPU have 
8  processors.
-----------
There are 
64.67547542837015 %  free memory.
CPU have 
8  processors.
-----------
There are 
57.618177784023494 %  free memory.
CPU have 
8  processors.
-----------
There are 
48.79652835643279 %  free memory.
CPU have 
8  processors.
-----------
There are 
41.739230712086126 %  free memory.
CPU have 
8  processors.
-----------
There are 
32.91758128449542 %  free memory.
CPU have 
8  processors.
-----------
There are 
24.095931856904713 %  free memory.
System will start memory Garbage Collection. Now we have 
70424  KB free memory.
After the Garbage Collection, we have 
258135  KB free memory.
CPU have 
8  processors.
-----------
There are 
81.32306278893708 %  free memory.
Last freeMemory 
=   258135  KB, now it is  237681  KB.
Last totalMemory 
=   380108  KB, now it is  380108  KB.
Last maxMemory 
=   1875378  KB, now it is  1875378  KB.
CPU have 
8  processors.
-----------
There are 
72.5752415442342 %  free memory.
CPU have 
8  processors.
-----------
There are 
65.57687068029719 %  free memory.
CPU have 
8  processors.
-----------
There are 
56.828918049238894 %  free memory.
CPU have 
8  processors.
-----------
There are 
49.83056634581206 %  free memory.
CPU have 
8  processors.
-----------
There are 
41.08271772895181 %  free memory.
CPU have 
8  processors.
-----------
There are 
32.33487732373877 %  free memory.
CPU have 
8  processors.
-----------
There are 
25.33650645980177 %  free memory.
System will start memory Garbage Collection. Now we have 
74050  KB free memory.
After the Garbage Collection, we have 
229217  KB free memory.
CPU have 
8  processors.
-----------
There are 
71.73676393326296 %  free memory.
Last freeMemory 
=   229217  KB, now it is  209663  KB.
Last totalMemory 
=   380108  KB, now it is  380108  KB.
Last maxMemory 
=   1875378  KB, now it is  1875378  KB.
CPU have 
8  processors.
-----------
There are 
63.37379248412019 %  free memory.
CPU have 
8  processors.
-----------
There are 
55.01088399093938 %  free memory.
CPU have 
8  processors.
-----------
There are 
46.64788243242348 %  free memory.
CPU have 
8  processors.
-----------
There are 
38.28488087390758 %  free memory.
CPU have 
8  processors.
-----------
There are 
31.59450152482077 %  free memory.
CPU have 
8  processors.
-----------
There are 
23.231593031639967 %  free memory.
System will start memory Garbage Collection. Now we have 
67898  KB free memory.
After the Garbage Collection, we have 
203384  KB free memory.
CPU have 
8  processors.
-----------
There are 
61.86563040788292 %  free memory.
Last freeMemory 
=   203384  KB, now it is  180813  KB.
Last totalMemory 
=   380108  KB, now it is  380108  KB.
Last maxMemory 
=   1875378  KB, now it is  1875378  KB.
CPU have 
8  processors.
-----------




我最近(2012-11-6 Tuesday 至 2012-11-20 Tuesday)参加了一个博客大赛。欢迎来给我投一票~
投票地址: http://blog.51cto.com/contest2012/5523233 每个 IP 每天可以投一票哦~

本文也发表在我的其他空间。
CSDN : http://blog.csdn.net/shanelooli/article/details/8176938
开源中国: http://my.oschina.net/shane1984/blog/88803
51CTO : http://shanelooli.blog.51cto.com/5523233/1058490



http://www.iteye.com/topic/1127731




















你可能感兴趣的:(利用 Runtime 监控 Java 系统资源)