但是可以通过前后对比法进行阶段性监控与分析。
首先加入一个静态方法:
public static long getMemory() {
return RuntimegetRuntime()freeMemory();
}
这个是查看运行时空闲内存的语句。
所以应该在需要检测的线程执行点前后进行插桩。
long point1 = getMemory();
线程调用
long point2 = getMemory();
注意:另外,在这个过程中不应该有其他的干扰(调用其他线程或者其他 *** 作)
甚至可以在线程中进行插桩,然后分析所有点的数值变化,根据数值差,就可以得出答案。java中可以用getBytes()length获取字符串占用内容的大小,原理是java中任何字符都采用Unicode编码,所以衡量占用内存大小采用占用的字节数。
举例如下:
public class TestStringSize {
public static final void main(String[] args) {
Systemoutprintln("占用内存大小:"+"学java"getBytes()length);
}
}
输出结果:
占用内存大小:6 byte
使用java自带的性能分析工具jvisualvm , 可以方便的查看内存, 对象, 线程等多种信息
win+R 然后输入 jvisualvm 回车即可效果如下图
首先
创建一个Bean用来存贮要得到的信
public class MonitorInfoBean {
/ 可使用内存 /
private long totalMemory;
/ 剩余内存 /
private long freeMemory;
/ 最大可使用内存 /
private long maxMemory;
/ *** 作系统 /
private String osName;
/ 总的物理内存 /
private long totalMemorySize;
/ 剩余的物理内存 /
private long freePhysicalMemorySize;
/ 已使用的物理内存 /
private long usedMemory;
/ 线程总数 /
private int totalThread;
/ cpu使用率 /
private double cpuRatio;
public long getFreeMemory() {
return freeMemory;
}
public void setFreeMemory(long freeMemory) {
thisfreeMemory = freeMemory;
}
public long getFreePhysicalMemorySize() {
return freePhysicalMemorySize;
}
public void setFreePhysicalMemorySize(long freePhysicalMemorySize) {
thisfreePhysicalMemorySize = freePhysicalMemorySize;
}
public long getMaxMemory() {
return maxMemory;
}
public void setMaxMemory(long maxMemory) {
thismaxMemory = maxMemory;
}
public String getOsName() {
return osName;
}
public void setOsName(String osName) {
thisosName = osName;
}
public long getTotalMemory() {
return totalMemory;
}
public void setTotalMemory(long totalMemory) {
thistotalMemory = totalMemory;
}
public long getTotalMemorySize() {
return totalMemorySize;
}
public void setTotalMemorySize(long totalMemorySize) {
thistotalMemorySize = totalMemorySize;
}
public int getTotalThread() {
return totalThread;
}
public void setTotalThread(int totalThread) {
thistotalThread = totalThread;
}
public long getUsedMemory() {
return usedMemory;
}
public void setUsedMemory(long usedMemory) {
thisusedMemory = usedMemory;
}
public double getCpuRatio() {
return cpuRatio;
}
public void setCpuRatio(double cpuRatio) {
thiscpuRatio = cpuRatio;
}
}
之后,建立bean的接口
public interface IMonitorService {
public MonitorInfoBean getMonitorInfoBean() throws Exception;
}
然后,就是最关键的,得到cpu的利用率,已用内存,可用内存,最大内存等信息。
import javaioInputStreamReader;
import javaioLineNumberReader;
import sunmanagementManagementFactory;
import comsunmanagementOperatingSystemMXBean;
import javaio;
import javautilStringTokenizer;
/
获取系统信息的业务逻辑实现类
@author GuoHuang
/
public class MonitorServiceImpl implements IMonitorService {
private static final int CPUTIME = 30;
private static final int PERCENT = 100;
private static final int FAULTLENGTH = 10;
private static final File versionFile = new File("/proc/version");
private static String linuxVersion = null;
/
获得当前的监控对象
@return 返回构造好的监控对象
@throws Exception
@author GuoHuang
/
public MonitorInfoBean getMonitorInfoBean() throws Exception {
int kb = 1024;
// 可使用内存
long totalMemory = RuntimegetRuntime()totalMemory() / kb;
// 剩余内存
long freeMemory = RuntimegetRuntime()freeMemory() / kb;
// 最大可使用内存
long maxMemory = RuntimegetRuntime()maxMemory() / kb;
OperatingSystemMXBean osmxb = (OperatingSystemMXBean) ManagementFactory
getOperatingSystemMXBean();
// *** 作系统
String osName = SystemgetProperty("osname");
// 总的物理内存
long totalMemorySize = osmxbgetTotalPhysicalMemorySize() / kb;
// 剩余的物理内存
long freePhysicalMemorySize = osmxbgetFreePhysicalMemorySize() / kb;
// 已使用的物理内存
long usedMemory = (osmxbgetTotalPhysicalMemorySize() - osmxb
getFreePhysicalMemorySize())
/ kb;
// 获得线程总数
ThreadGroup parentThread;
for (parentThread = ThreadcurrentThread()getThreadGroup(); parentThread
getParent() != null; parentThread = parentThreadgetParent())
;
int totalThread = parentThreadactiveCount();
double cpuRatio = 0;
if (osNametoLowerCase()startsWith("windows")) {
cpuRatio = thisgetCpuRatioForWindows();
}
else {
cpuRatio = thisgetCpuRateForLinux();
}
// 构造返回对象
MonitorInfoBean infoBean = new MonitorInfoBean();
infoBeansetFreeMemory(freeMemory);
infoBeansetFreePhysicalMemorySize(freePhysicalMemorySize);
infoBeansetMaxMemory(maxMemory);
infoBeansetOsName(osName);
infoBeansetTotalMemory(totalMemory);
infoBeansetTotalMemorySize(totalMemorySize);
infoBeansetTotalThread(totalThread);
infoBeansetUsedMemory(usedMemory);
infoBeansetCpuRatio(cpuRatio);
return infoBean;
}
private static double getCpuRateForLinux(){
InputStream is = null;
InputStreamReader isr = null;
BufferedReader brStat = null;
StringTokenizer tokenStat = null;
try{
Systemoutprintln("Get usage rate of CUP , linux version: "+linuxVersion);
Process process = RuntimegetRuntime()exec("top -b -n 1");
is = processgetInputStream();
isr = new InputStreamReader(is);
brStat = new BufferedReader(isr);
if(linuxVersionequals("24")){
brStatreadLine();
brStatreadLine();
brStatreadLine();
brStatreadLine();
tokenStat = new StringTokenizer(brStatreadLine());
tokenStatnextToken();
tokenStatnextToken();
String user = tokenStatnextToken();
tokenStatnextToken();
String system = tokenStatnextToken();
tokenStatnextToken();
String nice = tokenStatnextToken();
Systemoutprintln(user+" , "+system+" , "+nice);
user = usersubstring(0,userindexOf("%"));
system = systemsubstring(0,systemindexOf("%"));
nice = nicesubstring(0,niceindexOf("%"));
float userUsage = new Float(user)floatValue();
float systemUsage = new Float(system)floatValue();
float niceUsage = new Float(nice)floatValue();
return (userUsage+systemUsage+niceUsage)/100;
}else{
brStatreadLine();
brStatreadLine();
tokenStat = new StringTokenizer(brStatreadLine());
tokenStatnextToken();
tokenStatnextToken();
tokenStatnextToken();
tokenStatnextToken();
tokenStatnextToken();
tokenStatnextToken();
tokenStatnextToken();
String cpuUsage = tokenStatnextToken();
Systemoutprintln("CPU idle : "+cpuUsage);
Float usage = new Float(cpuUsagesubstring(0,cpuUsageindexOf("%")));
return (1-usagefloatValue()/100);
}
} catch(IOException ioe){
Systemoutprintln(ioegetMessage());
freeResource(is, isr, brStat);
return 1;
} finally{
freeResource(is, isr, brStat);
}
}public class RuntimeDemo01{
public static void main(String args[]){
Runtime run = RuntimegetRuntime(); // 通过Runtime类的静态方法进行实例化 *** 作
Systemoutprintln("JVM最大内存量:" + runmaxMemory()) ; // 观察最大的内存,根据机器的不同,环境也会有所不同
Systemoutprintln("JVM空闲内存量:" + runfreeMemory()) ; // 取得程序运行的空闲内存 }}我来解释一下你遇到的不解:
你所看到的现象也是真的。之所以RunTime的函数报告的内存与你看到的不一样是因为java运行是以虚拟机为单位。她报告的都是虚拟机的情况。
而在一个windows系统里,你可以启动安装多个虚拟机。而每个虚拟机在启动的时候,并不能得到windows系统的全部资源,jvm的资源也由windows来分配。windows所掌管的就是你硬件上的256M,
而jvm得到的仅是部分。
但对于运行在jvm里的java程序,当然只探测jvm的资源情况。
如果你非要让java程序跑到jvm之外的环境去探测实际硬件环境,那就只有native code了。我晕~~还是不对啊我运行的结果和你的一模一样
可我的内存是256M的而且可用内存肯定不对(不可能只有1M多)
欢迎分享,转载请注明来源:内存溢出
评论列表(0条)