VS2008下编纂的程序,能在win7系统上正常运行,但是使用win server2008系统时,程序运行一段时间后卡死

VS2008下编写的程序,能在win7系统上正常运行,但是使用win server2008系统时,程序运行一段时间后卡死
程序主要是用来进行图片数据的处理,也就是将相机采集到的数据进行压缩,然后保存。数据压缩采用libjpeg-9的方式先在内存中进行压缩,然后进行存储和显示。由于图片数据量过大(每秒几百兆),所以在程序采用了线程池的方式,循环对BUFFER内的数据进行处理。
出现的问题:
此程序在单个CPU、win7系统的工控机上能够正常运行,数据处理无异常,内存释放也无异常。但是在4个CPU(8核16线程)、win server2008系统的服务器上运行时就出现问题了。
如果连接的相机过多(相应的数据量更大)时,程序运行一会就中断了,如果连接的相机少,也运行不了多久,程序也会中断。
打开任务管理器查看时发现,物理内存在一直增长,并且,每次增加到54%时程序就死掉了。
堆栈查看错误时,发现出错的地方是在监控线程里的申请内存的地方(new unsigned char[image_size]);申请的内存空间是有点大,每张图片得有29M,程序中使用线程池来管理数据处理的工作项,每张图片处理完后都会进行资源释放,在win7系统下,资源释放都正常,但是在服务器时就不正常了。不知道有没有知道这是什么情况的大牛,望指点,感激不尽!

贴上部分代码:
//存放每张图片的图片信息,用于压缩和保存的参数传递
struct struct_ImageInfo *pImageStruct = new struct struct_ImageInfo;
pImageStruct->m_gEvent = CreateEvent(NULL,FALSE,FALSE,NULL);
pImageStruct->m_gDisplayEvent = CreateEvent(NULL,FALSE,FALSE,NULL);
pImageStruct->m_ImageSeq = m_iImageTricout;
pImageStruct->m_ListPosition = NULL;
pImageStruct->m_nDatasize = static_cast<unsigned long>(m_ImageWidth * m_ImageHeight);
pImageStruct->m_pCamera = this;
pImageStruct->m_pDestImageData = NULL;
pImageStruct->m_pSrcImageData = new unsigned char[image_size];
memmove_s(pImageStruct->m_pSrcImageData, image_size, m_pImageData, image_size);
pImageStruct->m_ListPosition = m_ListOfImageInfo.AddHead(pImageStruct);

压缩函数代码(压缩代码是libjpeg标准代码,此处只贴上资源释放的代码,代码中的控制标记控制为不保存也不显示,仅仅是压缩,完事后立马释放):
	//释放资源
(pStructSrcImage->m_pCamera)->m_CamThreadPool.CloseWork(pStructSrcImage->m_pCompressWork);
//保存、显示;或者只保存、显示
if (pStructSrcImage->m_pCamera->m_bSaveFlag)
{
SetEvent(pStructSrcImage->m_gEvent);
}
else
{
//不保存,只显示
if (pStructSrcImage->m_pCamera->m_bImageShow)
{
SetEvent(pStructSrcImage->m_gDisplayEvent);
}
//不保存、不显示
else
{
//释放数据存储的内存
if ((pStructSrcImage->m_pSrcImageData) != NULL)
{
delete[] pStructSrcImage->m_pSrcImageData;
pStructSrcImage->m_pSrcImageData = NULL;
}
if (pStructSrcImage->m_pDestImageData != NULL)
{
delete[] pStructSrcImage->m_pDestImageData;
pStructSrcImage->m_pDestImageData = NULL;
}
//关闭事件句柄
if (pStructSrcImage->m_gEvent != NULL)
{
CloseHandle(pStructSrcImage->m_gEvent);
}
if (pStructSrcImage->m_gDisplayEvent != NULL)
{
CloseHandle(pStructSrcImage->m_gDisplayEvent);
}
//释放链表中对应位置上的结构体
if ((pStructSrcImage->m_pCamera)->m_ListOfImageInfo.GetAt(ps) != NULL)
{
delete (pStructSrcImage->m_pCamera)->m_ListOfImageInfo.GetAt(ps);
(pStructSrcImage->m_pCamera)->m_ListOfImageInfo.GetAt(ps) = NULL;
}
//将相应位置上的结构体从链表中删除
if ((pStructSrcImage->m_pCamera)->m_ListOfImageInfo.GetAt(ps) !=NULL)
{
(pStructSrcImage->m_pCamera)->m_ListOfImageInfo.RemoveAt(ps);
}
}
}

------解决方案--------------------
引用:
Quote: 引用:

server2008上用VS2008编译一下程序

在server2008上编译过了的,程序能够跑起来,但是中途总是停止

是不是内存申请不够了,用内存池等。
------解决方案--------------------
引用:
Quote: 引用:

new unsigned char[image_size]
捕获内存错误,当申请不能满足时,减少线程数量

4核8线程的CPU能负载起4个相机(win7)系统,那么服务器至少都是能够负载其4个的,实际情况却是即使4个也会出问题,再说,这个服务器是IBM的服务器,不至于会带不起的。而且每次都是物理内存到54%的时候才停,而不是到100%。
另外,我也试过控制线程的数量,将每个相机的线程池中线程上限控制在了5个,反倒给我的感觉是程序中断得更快了……


你的问题看起来是申请不到内存才崩溃的,跟多少线程应该没有太大的直接关系,另外并不是线程越多速度越快,因为线程调度需要很大的消耗
------解决方案--------------------
引用:
Quote: 引用:

弹出错误对话框了吗?

弹了,不错那个描述的具体内容我给忘了。break后调用堆栈看是new这儿出的错,应该是内存分配失败吧。现在奇怪的就是在相同负载的情况下,一个CPU的工控机能跑,服务器反倒不能跑了……

#pragma comment(linker, "/STACK:100000000,100000000")

把堆栈调大点试下
------解决方案--------------------
你单次申请的内存过大,造成系统没有那么的内存空间给你使用。你可以采用64位系统试试。
或者采用内存池的方式,这个内存池可以采用静态大小,比如你的照片大小为最大30MB,这个时候你可以申请30个大小的内存,循环使用。

------解决方案--------------------
#pragma comment(linker, "/STACK:100000000,100000000")

不知道这个管用不?
楼主也不来结
------解决方案--------------------
如果申请和释放都很频繁的话
尝试采用内存池的方式,可以提高性能和稳定性

------解决方案--------------------
引用:
如果申请和释放都很频繁的话
尝试采用内存池的方式,可以提高性能和稳定性

+1
使用内存池对于频繁申请、释放内存的应用是正解
可以防止内存碎片