项目遇到最大的困境,也不知道何去何从。

bbc9527 2013-08-04 10:04:34
写了好几个月,收尾阶段了,本来以为可以结束了
结果遇到了问题 实在无法解决。代码还算有点大,接近1W5行的样子
问题出在了使用了泛型list,里面都是存储结构体
然后大量的在调用过程中使用,调用过程又都是在线程里面。
线程要多次 启动和结束,每次启动和结束的时候都会发现内存一下子上去了,然后在线程运行中会发现内存也是缓慢增加的。用了工具定位,全部都定位到泛型list创建的位置,查了一下资料。有可能有几种原因。也不确定。(delphi2010)
1、泛型list里面的结构体是有string类型的,释放不干净,这个也不知道怎么处理。
2、泛型list在过程里面调用了clear方法,没有释放对象(这个我做过实验,貌似内存没增长)
3、泛型list本身就有问题,是一个编译器bug,需要版本更新。
4、我代码本身的问题,有些地方没释放,但是我是窗体创建的时候创建,窗体销毁的时候free的,最后也没提示内存泄露啊。在中间过程的内存不断上涨(多线程 启动之后 内存先增加再减少,然后稳定,线程结束之后重新启动 内存一下子增加了好多。中间我都是用clear去清理的不知道是不是这个原因)
5、问了论坛的一些朋友 一般给的代码都是 创建没多久就销毁了,问题是我的程序需要创建 之后 在线程里面多次操作
线程也是多次的 启动 退出 最后程序完全退出的时候才退出。(这样的话 借用别人的话来说 就是要考虑生命周期的问题)可是我不会处理
经过这几个月的代码编写,我深深的感到了delphi 程序员的无奈 资料很难找 问了之后 即使有回答的 也是要自己重新摸索好久。有些底层的东西 要自己处理 处理不好 往往问题很大。
诶,好多天没好好休息了。有愿意聊的,说个话。
聊的开心的就当散分吧。
...全文
230 10 打赏 收藏 转发到动态 举报
写回复
用AI写文章
10 条回复
切换为时间正序
请发表友善的回复…
发表回复
hsfzxjy 2013-08-06
  • 打赏
  • 举报
回复
对于某个特定类型就写个对应的代理类,类中包含一个私有的TList:
TSOList = class
private
  FList: TList;
public
  procedure Add(so: Tso);
  procedure Delete(i: integer);
  procedure Insert(i: integer;so: TSO);
  procedure Clear;

  contructor Create;
  destructor Destroy; override;
end;

constructor TSOList.Create;
begin
  FList := TList.Create;
end;

destructor TSOList.Destroy; 
begin
  FList.Free;
  inherited;
end;

procedure TSOList.Add(so: TSO);
begin
  FList.Add(@so);
  //这里相当于一个代理操作,下面几个类似,我便不重复叙述了
end;
这种方法我用了很久,虽说有些麻烦,但还是很安全。当你要用的数据结构并不多时,可以考虑
ysai 2013-08-06
  • 打赏
  • 举报
回复
泛型clear并不会释放其中的对象啊,如果做到谁分配谁保证释放,就没那么多内存泄露了
bbc9527 2013-08-06
  • 打赏
  • 举报
回复
问题找到原因并且解决了。感谢回复。
  • 打赏
  • 举报
回复
慢慢找bug吧,我对delphi的list还是比较放心,
  • 打赏
  • 举报
回复
1、string类型是生存期自管理的,我觉得对于delphi这么一个多年的编译器不太可能在这方面出现问题,这应该是你排查完其他所有bug的最后一步。另外如果你信不过string,你完全可以用pchar代替string,自己分配自己释放。 2、clear方法不会释放对象,只会清除entries,自己创建的对象必须自己释放。 3、这个问题参照第一个回答,我觉得这不太可能是delphi的问题。你也可以去官方看看有没有这个bug的记录。 4、调用free,只是保证对象在析构时,会析构它所包含的对象,但在堆中创建的对象必须要显示释放,析构不会自动去释放这些对象(在d7以前是这样,新版的应该这点是不会变的),例如TMyClass中你为一个指针p分配了内存,如果你在TMyClass的析构函数中没有显示释放p,那你调用TMyClass的free也不会释放p,就是说free只会保证调用析构函数,但你的析构函数是什么样的它不管。内存泄漏检测建议用e什么log的一个软件,很不错。 5、可以考虑线程池
  • 打赏
  • 举报
回复
估计是线程处理不好,导致内存溢出。 java和C#,都有内存回收机制,delphi7和C++等没有。 所以用delphi开发时,一定要注意对象的创建、释放。 如果是循环处理,或链表里有对象,还要注意clear(清除内存中,变量的堆栈区,而非栈区。) 我是窗体创建的时候创建,窗体销毁的时候free的, 最后也没提示内存泄露啊。在中间过程的内存不断上涨。 ---对象变量是一个,但中间可以创建多个对象给变量,最后free, 只是释放了最后一个创建的对象的堆栈区,其他先前几个未free,所以内存溢出了。 delphi是核心类库功能强,外围类功能弱,外围类种类有限。 所以很多时候靠第三方类来弥补。 楼主觉得累,可以改为C#开发。
LastAvengers 2013-08-04
  • 打赏
  • 举报
回复
不能帮上什么忙,楼主加油!
bbc9527 2013-08-04
  • 打赏
  • 举报
回复
般写个类包装一下看起来就和泛型差不多了。----------这个怎么写? 总有种感觉:泛型方便的同时又不太安全。不知道我说的对不对?毕竟没接触过泛型的内存管理。 听网上说泛型有不少BUG,我想还是等它成熟点再用。 具体怎么写?

type
Tso=packed record 
jiu:Integer;
zu:Integer; 
mu:Integer;  
sn:Tsn; 
end;


type
Tsn=packed record 
i:Integer; 
ng:Integer; 
sng:Integer; 
mng:Integer; 
je:Integer;
wi:Integer; 
di:Integer; 
mi:string;  
end;
比如这样的结构体 我想能跟泛型的list一样 可以增加 删除 清理 排序之类的操作
hsfzxjy 2013-08-04
  • 打赏
  • 举报
回复
没用过泛型,呵呵,一直用旧版的List,除了操作麻烦点感觉也没什么。一般写个类包装一下看起来就和泛型差不多了。 总有种感觉:泛型方便的同时又不太安全。不知道我说的对不对?毕竟没接触过泛型的内存管理。 听网上说泛型有不少BUG,我想还是等它成熟点再用。 注意休息!
bbc9527 2013-08-04
  • 打赏
  • 举报
回复
1、string类型是生存期自管理的,我觉得对于delphi这么一个多年的编译器不太可能在这方面出现问题,这应该是你排查完其他所有bug的最后一步。另外如果你信不过string,你完全可以用pchar代替string,自己分配自己释放。----这个没写过 而且是结构体 写起来很麻烦啊 2、clear方法不会释放对象,只会清除entries,自己创建的对象必须自己释放。---主要是想清理内存 不让内存暴涨 3、这个问题参照第一个回答,我觉得这不太可能是delphi的问题。你也可以去官方看看有没有这个bug的记录。----有一个朋友说有 ,我也不清楚,很少关注这个。 4、调用free,只是保证对象在析构时,会析构它所包含的对象,但在堆中创建的对象必须要显示释放,析构不会自动去释放这些对象(在d7以前是这样,新版的应该这点是不会变的),例如TMyClass中你为一个指针p分配了内存,如果你在TMyClass的析构函数中没有显示释放p,那你调用TMyClass的free也不会释放p,就是说free只会保证调用析构函数,但你的析构函数是什么样的它不管。内存泄漏检测建议用e什么log的一个软件,很不错。----我就是用那软件检测出来的,只是不知道怎么修改 他定位的地址全部在创建的地方。 5、可以考虑线程池------这样写法估计更复杂了 几个线程+临界 和协调 就已经很麻烦了 可否告之联系方式 bluekitty

16,742

社区成员

发帖
与我相关
我的任务
社区描述
Delphi 语言基础/算法/系统设计
社区管理员
  • 语言基础/算法/系统设计社区
加入社区
  • 近7日
  • 近30日
  • 至今
社区公告
暂无公告

试试用AI创作助手写篇文章吧