我在程序中会反复创建 并释放它,没有用 terminatethread 和exitthread,因为我用了freeonterminate:=true; 根据跟踪可以看到线程正常结束了,用CheckThreadFreed 也可以得到结束释放的返回。
但我的程序中有一个TADOQUERY的过程,创建一个TADOQUERY执行一个查询后释放。
程序运行中,会出现 outofmemory 错误,FASTMM提示“FastMM 已检测到一个错误, 当时正在进行 GetMem 操作. FastMM 检测到对已释放内存块内容的修改.”
但事实上,我的每个对象都有成对且有效的creat和free,在释放后,也没有对该对象进行操作。
对堆栈跟踪可以看到,是在新创建一个对象时,出现的。
当前线程的 ID 是 0x1F5C, 导致该错误的堆栈跟踪(返回地址):
40B3D4 [FastMM4][DebugGetMem]
40B62E [FastMM4][DebugReallocMem]
402F2F [System][@ReallocMem]
424C54 [Classes][TList.SetCapacity]
424ABC [Classes][TList.Grow]
4248CD [Classes][TList.Add]
42DE29 [Classes][TComponent.Insert]
42DE84 [Classes][TComponent.InsertComponent]
42DCCA [Classes][TComponent.Create]
4A3C40 [DB][TField.Create]
4A5517 [DB][TStringField.Create]
然后我不用这个TADOQUERY的过程,发现只要有其他需要分配内存的代码执行(对象自己的create)都会引起这种outofmemory。
我该怎么办?
9 个解决方案
#1
无限制的创建线程,而不释放,系统会承受不起的,不要滥用线程
#2
释放了的
从FASTMM中也可以看到
该内存块上一次分配于线程 0x2C3C, 当时的堆栈跟踪(返回地址):
402EF4 [System][@GetMem]
4042AF [System][TObject.NewInstance]
40468A [System][@ClassCreate]
42E355 [Classes][TThread.Create]
477518 [Controls][TWinControl.WndProc]
474287 [Controls][TControl.Perform]
79DC1E [work.pas][work][FW_synword][5407]
78757C [work.pas][work][addviewboxblank][421]
793DEA [work.pas][work][FW_getuserpara][3313]
78A551 [work.pas][work][TFrm_work.workfile][1181]
78BBB4 [work.pas][work][TFrm_work.Timer_timeoutTimer][1533]
该内存块上次被用于一个属于以下类的对象: Tsynthread
分配号码是: 163504
该内存块上一次释放于线程 0x257C, 当时的堆栈跟踪(返回地址):
402F1F [System][@FreeMem]
4042CD [System][TObject.FreeInstance]
4046D5 [System][@ClassDestroy]
42E46F [Classes][TThread.Destroy]
404313 [System][TObject.Free]
42E322 [Classes][ThreadProc]
4051FE [System][ThreadWrapper]
7C82482F [Unknown function at GetModuleHandleA]
线程,有创建和释放。
从FASTMM中也可以看到
该内存块上一次分配于线程 0x2C3C, 当时的堆栈跟踪(返回地址):
402EF4 [System][@GetMem]
4042AF [System][TObject.NewInstance]
40468A [System][@ClassCreate]
42E355 [Classes][TThread.Create]
477518 [Controls][TWinControl.WndProc]
474287 [Controls][TControl.Perform]
79DC1E [work.pas][work][FW_synword][5407]
78757C [work.pas][work][addviewboxblank][421]
793DEA [work.pas][work][FW_getuserpara][3313]
78A551 [work.pas][work][TFrm_work.workfile][1181]
78BBB4 [work.pas][work][TFrm_work.Timer_timeoutTimer][1533]
该内存块上次被用于一个属于以下类的对象: Tsynthread
分配号码是: 163504
该内存块上一次释放于线程 0x257C, 当时的堆栈跟踪(返回地址):
402F1F [System][@FreeMem]
4042CD [System][TObject.FreeInstance]
4046D5 [System][@ClassDestroy]
42E46F [Classes][TThread.Destroy]
404313 [System][TObject.Free]
42E322 [Classes][ThreadProc]
4051FE [System][ThreadWrapper]
7C82482F [Unknown function at GetModuleHandleA]
线程,有创建和释放。
#3
把FreeOnTerminate去掉,原因是你设置了线程的FreeOnTerminate,这样会导致线程执行完毕的时候,自动释放线程对象,这样就导致了这个线程对象是在主线程中申请的,但是在分线程释放的,一般解决办法是线程执行完毕手动释放。
#4
在编写线程的时候,要遵守基本的原则,即本线程申请的内存,本线程负责释放,主线程申请的TThread,应该在主线程释放,而不是用FreeOnTerminate来释放。
#5
这个是我测试用的,
用freeonterminate是为了我真正要用的线程,里面使用了Indy的idftp,它会因某些原因阻塞而死锁,用tthread.free时,因为它会waitfor,结果程序就会无响应死掉。
用freeonterminate,当出现这种情况,我就可以不去管它,等关掉程序时会释放这种卡死的线程。
用freeonterminate是为了我真正要用的线程,里面使用了Indy的idftp,它会因某些原因阻塞而死锁,用tthread.free时,因为它会waitfor,结果程序就会无响应死掉。
用freeonterminate,当出现这种情况,我就可以不去管它,等关掉程序时会释放这种卡死的线程。
#6
另外,我测试了在主线程使用 free,仍然会出现outofmemory,有时不报错,直接就把程序自动关闭了。
#7
Out Of Memory是内存用光了,用FastMM多检查一下。
#8
outofmemory应该是SQLDebug_Fan 所说的原因,线程自释放会出问题,应该和delphi7的内存管理有关。
但是,现在仍然存在的问题就是不断创建、释放,然后某个时刻 程序崩溃,自动关闭。
我观察任务管理器,线程数量一直稳定在10-11,因为我同时只用了一个线程,创建后就11,释放后就10,句柄数也很稳定。
不知道为什么会崩溃,FASTMM跟踪不到,eurekalog也跟踪不到。
但是,现在仍然存在的问题就是不断创建、释放,然后某个时刻 程序崩溃,自动关闭。
我观察任务管理器,线程数量一直稳定在10-11,因为我同时只用了一个线程,创建后就11,释放后就10,句柄数也很稳定。
不知道为什么会崩溃,FASTMM跟踪不到,eurekalog也跟踪不到。
#9
确认TTHREAD类不能用自释放
#1
无限制的创建线程,而不释放,系统会承受不起的,不要滥用线程
#2
释放了的
从FASTMM中也可以看到
该内存块上一次分配于线程 0x2C3C, 当时的堆栈跟踪(返回地址):
402EF4 [System][@GetMem]
4042AF [System][TObject.NewInstance]
40468A [System][@ClassCreate]
42E355 [Classes][TThread.Create]
477518 [Controls][TWinControl.WndProc]
474287 [Controls][TControl.Perform]
79DC1E [work.pas][work][FW_synword][5407]
78757C [work.pas][work][addviewboxblank][421]
793DEA [work.pas][work][FW_getuserpara][3313]
78A551 [work.pas][work][TFrm_work.workfile][1181]
78BBB4 [work.pas][work][TFrm_work.Timer_timeoutTimer][1533]
该内存块上次被用于一个属于以下类的对象: Tsynthread
分配号码是: 163504
该内存块上一次释放于线程 0x257C, 当时的堆栈跟踪(返回地址):
402F1F [System][@FreeMem]
4042CD [System][TObject.FreeInstance]
4046D5 [System][@ClassDestroy]
42E46F [Classes][TThread.Destroy]
404313 [System][TObject.Free]
42E322 [Classes][ThreadProc]
4051FE [System][ThreadWrapper]
7C82482F [Unknown function at GetModuleHandleA]
线程,有创建和释放。
从FASTMM中也可以看到
该内存块上一次分配于线程 0x2C3C, 当时的堆栈跟踪(返回地址):
402EF4 [System][@GetMem]
4042AF [System][TObject.NewInstance]
40468A [System][@ClassCreate]
42E355 [Classes][TThread.Create]
477518 [Controls][TWinControl.WndProc]
474287 [Controls][TControl.Perform]
79DC1E [work.pas][work][FW_synword][5407]
78757C [work.pas][work][addviewboxblank][421]
793DEA [work.pas][work][FW_getuserpara][3313]
78A551 [work.pas][work][TFrm_work.workfile][1181]
78BBB4 [work.pas][work][TFrm_work.Timer_timeoutTimer][1533]
该内存块上次被用于一个属于以下类的对象: Tsynthread
分配号码是: 163504
该内存块上一次释放于线程 0x257C, 当时的堆栈跟踪(返回地址):
402F1F [System][@FreeMem]
4042CD [System][TObject.FreeInstance]
4046D5 [System][@ClassDestroy]
42E46F [Classes][TThread.Destroy]
404313 [System][TObject.Free]
42E322 [Classes][ThreadProc]
4051FE [System][ThreadWrapper]
7C82482F [Unknown function at GetModuleHandleA]
线程,有创建和释放。
#3
把FreeOnTerminate去掉,原因是你设置了线程的FreeOnTerminate,这样会导致线程执行完毕的时候,自动释放线程对象,这样就导致了这个线程对象是在主线程中申请的,但是在分线程释放的,一般解决办法是线程执行完毕手动释放。
#4
在编写线程的时候,要遵守基本的原则,即本线程申请的内存,本线程负责释放,主线程申请的TThread,应该在主线程释放,而不是用FreeOnTerminate来释放。
#5
这个是我测试用的,
用freeonterminate是为了我真正要用的线程,里面使用了Indy的idftp,它会因某些原因阻塞而死锁,用tthread.free时,因为它会waitfor,结果程序就会无响应死掉。
用freeonterminate,当出现这种情况,我就可以不去管它,等关掉程序时会释放这种卡死的线程。
用freeonterminate是为了我真正要用的线程,里面使用了Indy的idftp,它会因某些原因阻塞而死锁,用tthread.free时,因为它会waitfor,结果程序就会无响应死掉。
用freeonterminate,当出现这种情况,我就可以不去管它,等关掉程序时会释放这种卡死的线程。
#6
另外,我测试了在主线程使用 free,仍然会出现outofmemory,有时不报错,直接就把程序自动关闭了。
#7
Out Of Memory是内存用光了,用FastMM多检查一下。
#8
outofmemory应该是SQLDebug_Fan 所说的原因,线程自释放会出问题,应该和delphi7的内存管理有关。
但是,现在仍然存在的问题就是不断创建、释放,然后某个时刻 程序崩溃,自动关闭。
我观察任务管理器,线程数量一直稳定在10-11,因为我同时只用了一个线程,创建后就11,释放后就10,句柄数也很稳定。
不知道为什么会崩溃,FASTMM跟踪不到,eurekalog也跟踪不到。
但是,现在仍然存在的问题就是不断创建、释放,然后某个时刻 程序崩溃,自动关闭。
我观察任务管理器,线程数量一直稳定在10-11,因为我同时只用了一个线程,创建后就11,释放后就10,句柄数也很稳定。
不知道为什么会崩溃,FASTMM跟踪不到,eurekalog也跟踪不到。
#9
确认TTHREAD类不能用自释放