且构网

分享程序员开发的那些事...
且构网 - 分享程序员编程开发的那些事

应用程序消耗接近100%的CPU,如何分析和确定原因

更新时间:2023-11-13 09:36:10

Mark,


你是否发现这些尖峰正在影响

应用程序的性能,或整体机器的性能?


尖峰很可能是垃圾的结果

收集和内存管理。

-

- Nicholas Paldino [.NET / C#MVP]

- mv*@spam.guard.caspershouse.com


< Lo ***** @ hotmail.com>在消息中写道

news:11 ********************** @ z14g2000cwz.googlegr oups.com ...
Mark,

Are you finding that these spikes are impacting the performance of the
application, or, the performance of the machine overall?

It''s very possible that the spikes could be the result of garbage
collection and memory management.
--
- Nicholas Paldino [.NET/C# MVP]
- mv*@spam.guard.caspershouse.com

<Lo*****@hotmail.com> wrote in message
news:11**********************@z14g2000cwz.googlegr oups.com...
你好,

我最近写了一个应用程序,用于测试老化室中的单元。它使用两个外部库,需要使用
P\Invoke才能使用它们。有一个主线程和一个
二级轮询线程。每隔一段时间,这个过程就会消耗接近100%的CPU,但我不明白为什么。我想知道如何确定问题的原因?我应该使用什么样的工具或工具来确定代码的哪个部分导致问题。非常感谢任何帮助。

我知道在硬件世界中我可以实现一个监视器来重新启动系统,这样的东西会有用吗?我必须保持跟踪系统因此会运行得更慢并且消耗更多的资源,但是当过程有问题时我也许能够恢复???

Mark
Hello,

I recently wrote an application that is used for testing units in a
burn-in chamber. It uses two external library that require the use of
P\Invoke in order to work with them. There is a primary thread and a
secondary polling thread. Every once in a while the process will
consume close to 100% of the CPU, but I am unclear why. I am wondering
how would I go about determine the cause of the problem? What sort of
tools or instrumentation should I use in order to determine what part
of the code is causing the problem. Any help is greatly appreciated.

I know in the hardware world I could implement a watchdog to restart
the sytem, would something like that be useful? I would have to keep
track of the system thus is would run slower and consume more
resources, but I might be able to recover when the process has
problems???

Mark



Nicholas,


对不起,我没有给自己解释得太好。实际上当

进程消耗接近100%的CPU时它会保持在那个级别,直到

我杀了这个任务。我让它运行几分钟,看看它是否会恢复,但它从来没有这样做我杀了这个任务。我不清楚什么是

触发它。


对于P / Invoke函数,它们看起来如下


[DllImport(" SiF32xUSB.DLL",EntryPoint =" F32x_Write",SetLastError

= true,

CharSet = CharSet.Unicode,ExactSpelling = true,

CallingConvention = CallingConvention.StdCall)]

private static extern

System.Int32 F32x_Write(System.UInt32句柄,

System.IntPtr Buffer,

System.UInt32 NumBytesToRead,

ref System.UInt32

NumBytesWrittenToDevice

);


那么使用这个函数的对应方法如下:


public bool Write(UInt32 handle,byte [] buffer)

{

UInt32 numBytesWritten = 0x00;


GCHandle gch = GCHandle.Alloc(缓冲区,GCHandleType.Pinned);


m_LastErrorCode =

(SI_RETURN_CODES)F32x_Write(句柄,

gch.AddrOfPinnedObject(),

(UInt32)buffer.Length,

ref numBytesWritten);


gch .Free();


if(m_LastErrorCode == SI_RETURN_CODES.SI_SUCCESS)

{

返回true;

}

其他

{

返回false;

}

}


我不知道这些声明中的任何一个是否导致问题

。我注意到我确实有一个P / Invoke函数,因为

内存没有被固定,因此GC可能在特定时间执行该b / b
并导致问题。这种方法看起来像


公共MMCThermocoupleTypes TCType

{

get {return m_TCType; }

套装

{

int apiResult;


试试

{

m_TCType = value;

apiResult = cbSetConfig((int)MCCCfgInfpType.BOARDINFO,

(int)m_USBTCBoardNum,

(int)m_ChamberTCChannel,

(int)MMMBoardCfgInfoType.BITCCHANTYPE,

(int)m_TCType

);

}

catch(例外)

{

// TODO:为此事件实现处理程序。 />
}

}

}


以m_开头的变量是该课程的成员,并且是私人的b $ b。也许GC正在这个特定的时间点移动内存导致问题?我真的不知道。


马克

Nicholas,

Sorry that I didn''t explain myself well enough. Actually when the
process consumes close to 100% of the CPU it stays at that level until
I kill the task. I have let it run a few minutes to see if it would
recover, but it never did so I killed the task. I am unclear what is
triggering it.

For the P/Invoke functions they look like the following

[DllImport("SiF32xUSB.DLL", EntryPoint = "F32x_Write", SetLastError
= true,
CharSet = CharSet.Unicode, ExactSpelling = true,
CallingConvention = CallingConvention.StdCall)]
private static extern
System.Int32 F32x_Write( System.UInt32 Handle,
System.IntPtr Buffer,
System.UInt32 NumBytesToRead,
ref System.UInt32
NumBytesWrittenToDevice
);

Then the correspond method that uses this function is as follows:

public bool Write( UInt32 handle, byte[] buffer )
{
UInt32 numBytesWritten = 0x00;

GCHandle gch = GCHandle.Alloc( buffer, GCHandleType.Pinned );

m_LastErrorCode =
(SI_RETURN_CODES)F32x_Write( handle,
gch.AddrOfPinnedObject(),
(UInt32)buffer.Length,
ref numBytesWritten );

gch.Free();

if ( m_LastErrorCode == SI_RETURN_CODES.SI_SUCCESS )
{
return true;
}
else
{
return false;
}
}

I don''t know if either of these declarations are causing the problems
or not. I did notice I do have one P/Invoke function to where the
memory isn''t pinned therefore perhaps the GC is executing at that
particular time and causing the problem. That method looks like

public MMCThermocoupleTypes TCType
{
get { return m_TCType; }
set
{
int apiResult;

try
{
m_TCType = value;
apiResult = cbSetConfig( (int)MCCCfgInfpType.BOARDINFO,
(int)m_USBTCBoardNum,
(int)m_ChamberTCChannel,

(int)MMMBoardCfgInfoType.BITCCHANTYPE,
(int)m_TCType
);
}
catch ( Exception )
{
// TODO: Implement handler for this event.
}
}
}

The variables that start with "m_" are members to the class and are
private. Perhaps the GC is moving memory around at this particular
point in time causing problems? I really don''t know.

Mark


从我所看到的,你不要'' t需要在将字节数组传递给你的未管理代码之前将其固定。编组人员会将阵列固定在内存中,然后在完成后释放它。


至于尖峰,这里没有什么我会看到的当你发布固定变量时,这会导致这种情况。您的申请是否在这段时间内没有回应?b $ b?您没有任何迹象表明100%

利用率会对您的应用或机器产生负面影响。


-

- Nicholas Paldino [.NET / C#MVP]

- mv*@spam.guard.caspershouse.com


< Lo ***** @ hotmail.com>在消息中写道

news:11 ********************** @ g14g2000cwa.googlegr oups.com ...
From what I can see, you don''t need to pin the byte array before passing
it to your unamanged code. The marshaler will pin the array in memory for
you, and release it when done.

As for the spike, there is nothing here that I would see that would
cause this, as you are releasing the pinned variable. Does your application
not respond during this time? You haven''t given any indication that 100%
utilization is impacting your app, or the machine negatively.

--
- Nicholas Paldino [.NET/C# MVP]
- mv*@spam.guard.caspershouse.com

<Lo*****@hotmail.com> wrote in message
news:11**********************@g14g2000cwa.googlegr oups.com...
尼古拉斯,

很抱歉,我没有给自己解释得太好。实际上,当
进程消耗接近100%的CPU时,它会保持在该级别,直到我终止任务。我让它运行几分钟,看看它是否会恢复,但它从未这样做,我杀死了这个任务。我不清楚是什么触发它。

对于P / Invoke函数,它们看起来如下

[DllImport(" SiF32xUSB.DLL",EntryPoint) =" F32x_Write",SetLastError
= true,
CharSet = CharSet.Unicode,ExactSpelling = true,
CallingConvention = CallingConvention.StdCall)]
私有静态外部
System.Int32 F32x_Write(System.UInt32句柄,
System.IntPtr缓冲区,
System.UInt32 NumBytesToRead,
参考System.UInt32
NumBytesWrittenToDevice
);

然后使用此函数的对应方法如下:

public bool Write(UInt32 handle,byte [] buffer)
{
UInt32 numBytesWritten = 0x00 ;

GCHandle gch = GCHandle.Alloc(缓冲区,GCHandleType.Pinned);

m_LastErrorCo de =
(SI_RETURN_CODES)F32x_Write(句柄,
gch.AddrOfPinnedObject(),
(UInt32)buffer.Length,
ref numBytesWritten);

gch.Free();

if(m_LastErrorCode == SI_RETURN_CODES.SI_SUCCESS)
{
返回true;
}

{
返回false;
}


我不知道这些声明中的任何一个是否导致了问题。我注意到我确实有一个P / Invoke函数来确定内存没有被固定,因此GC可能正在特定时间执行并导致问题。该方法看起来像公共MMCThermocoupleTypes TCType
{
get {return m_TCType; }
设置
{apiResult;

尝试
{
m_TCType = value;
apiResult = cbSetConfig((int )MCCCfgInfpType.BOARDINFO,
(int)m_USBTCBoardNum,
(int)m_ChamberTCChannel,

(int)MMMBoardCfgInfoType.BITCCHANTYPE,
(int)m_TCType
);
}
catch(例外)
// TODO:为此次活动实施处理程序。
}
}
}

以m_开头的变量是班上的成员,并且是私人的。也许GC正在这个特定的时间点移动内存导致问题?我真的不知道。

马克
Nicholas,

Sorry that I didn''t explain myself well enough. Actually when the
process consumes close to 100% of the CPU it stays at that level until
I kill the task. I have let it run a few minutes to see if it would
recover, but it never did so I killed the task. I am unclear what is
triggering it.

For the P/Invoke functions they look like the following

[DllImport("SiF32xUSB.DLL", EntryPoint = "F32x_Write", SetLastError
= true,
CharSet = CharSet.Unicode, ExactSpelling = true,
CallingConvention = CallingConvention.StdCall)]
private static extern
System.Int32 F32x_Write( System.UInt32 Handle,
System.IntPtr Buffer,
System.UInt32 NumBytesToRead,
ref System.UInt32
NumBytesWrittenToDevice
);

Then the correspond method that uses this function is as follows:

public bool Write( UInt32 handle, byte[] buffer )
{
UInt32 numBytesWritten = 0x00;

GCHandle gch = GCHandle.Alloc( buffer, GCHandleType.Pinned );

m_LastErrorCode =
(SI_RETURN_CODES)F32x_Write( handle,
gch.AddrOfPinnedObject(),
(UInt32)buffer.Length,
ref numBytesWritten );

gch.Free();

if ( m_LastErrorCode == SI_RETURN_CODES.SI_SUCCESS )
{
return true;
}
else
{
return false;
}
}

I don''t know if either of these declarations are causing the problems
or not. I did notice I do have one P/Invoke function to where the
memory isn''t pinned therefore perhaps the GC is executing at that
particular time and causing the problem. That method looks like

public MMCThermocoupleTypes TCType
{
get { return m_TCType; }
set
{
int apiResult;

try
{
m_TCType = value;
apiResult = cbSetConfig( (int)MCCCfgInfpType.BOARDINFO,
(int)m_USBTCBoardNum,
(int)m_ChamberTCChannel,

(int)MMMBoardCfgInfoType.BITCCHANTYPE,
(int)m_TCType
);
}
catch ( Exception )
{
// TODO: Implement handler for this event.
}
}
}

The variables that start with "m_" are members to the class and are
private. Perhaps the GC is moving memory around at this particular
point in time causing problems? I really don''t know.

Mark