如何获取单个程序进程所占用的内存空间大小

如何获取单个程序进程所占用的内存空间大小,第1张

有限制,你首先需要分清,物理内存和虚拟内存的概念。然后你需要知道什么是“虚空间”。
物理内存到虚拟内存的转换因不同
CPU
和 *** 作系统的不同而不同,而且机制过于复杂,不说了。
首先,不是说你的机器有
15G
的物理内存就可以分配到内存。为什么呢?
因为 *** 作系统对进程的内存管理首先是分配给进程一个“虚空间”,用户根本看不见物理内存,它所有的内存都从“虚空间”种分配。
比如
Windows

X86
上分配给每个进程
4G
的虚空间,这个虚空间需要软件和硬件共同实现,同样,机制过于复杂,不说了。其中
Windows
系统占用
2G,分配给用户
2G。另外
Windows
会把这个空间划分成若干个区域,malloc
的内存就来自其中的
heap
区,加入系统给你的
heap
区域是
500M,那么你只能申请总共小于
500M
的虚拟内存,而不管你的物理内存大于
500M;同样你即使只有
10M
的物理内存剩余了,一个新创建的进程照样可以分配到
500M
的虚拟空间(只要你的硬盘足够大,这个涉及到交换技术,过于复杂,不说了)。

这个需要进进程管理查看
如何打开进程管理器
快捷键Ctrl+Alt+方向键下键(或者小键盘的Enter键)
另一种方法,就是鼠标移至屏幕下方的图标栏,右击鼠标,选择任务管理器
在任务管理器--进程里面就可以看到那些那些程序正在运行
如果想看CPU占用率排行,点击一下CPU就会把CPU占用率最高的按顺序排布下来

方法如下:
首先
创建一个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);
}
}

只要定义了并被链接器使用到的函数,生成可执行的代码就要占用空间,运行期载入内存的代码段和数据段。
POD(plain old data,数据类型中,非class类型以及兼容C的不含成员函数的class/struct类型)的类型定义只是编译期符号替换+静态类型检查,在运行期不会额外占用空间。
class类型中,非多态类(不含虚函数,非虚基类)的成员函数信息通常实现为运行期不占用额外空间。多态类一般为每个类保存一个虚表,实例对象中隐含一个指针指向这个表,以便在运行期确定需要调用的虚函数成员版本。此外关于虚基类可能有虚基类表等实现;以及额外的RTTI信息等;这些空间对程序员是不可见的。
引用有可能被优化掉,成为编译期常量写入代码段中,不额外占用空间。
除此之外的对象(变量、运行期常量,包括类的实例对象)一旦定义,即会在运行期占用空间(如果没被优化掉的话)。
变量所占用的内存空间是堆栈段。
对于运行期常量和全局/静态类型的变量,除非extern,否则一旦生命即自动初始化,对应于进程生成时即分配空间(分别位于常量区和静态区)进程结束以后会被释放。
非静态类型变量中,自动变量在定义时在栈分配空间,生命周期结束后被回收。非自动对象(例如通过new分配空间的)在堆中,需要程序员手动编写代码释放。
====
[原创回答团]


欢迎分享,转载请注明来源:内存溢出

原文地址: http://outofmemory.cn/yw/13198724.html

(0)
打赏 微信扫一扫 微信扫一扫 支付宝扫一扫 支付宝扫一扫
上一篇 2023-06-19
下一篇 2023-06-19

发表评论

登录后才能评论

评论列表(0条)

保存