我的程序中使用了线程,线程中使用了adodataset和idhttp
大致如下:
1、线程用的是TThread,主要代码在Execute,用完肯定全部释放动态创建的数据
2、adodataset在线程中需要open或访问或保存数据。
3、IDHTTP在线程中get方法打开网页。大致主要操作就是这样的。线程是根据情况反复创建实例和销毁实例。用内存泄露工具检查,只发现几个tstringlist没释放,这几个tstringlist也只是初始化读取少量几条数据,并在程序中只读不写,更没有ADD,应该不存在内存增加的状况。请问,这里内存不断增加会是什么原因?
我分析:
1、可能是线程释放不对?我已在每个实例线程开始段写了FreeOnTerminate := true;
例如procedure a.Execute;
begin
FreeOnTerminate := true;
tryfinally
...free;//凡是涉及到动态创建的全部释放
...
...
...
...free;//凡是涉及到动态创建的全部释放
end;
end;2、ADO内存泄露?我用的ADODATASET控件,会泄露吗?
我使用的方法就是open apeend edit post这几种,难道有泄露?3、由于反复创建和销毁实例线程,内存碎片得不到及时清理,导致内存不断增加?

解决方案 »

  1.   

    procedure a.Execute;
    begin
    FreeOnTerminate := true;
    tryfinally
    ...free;//凡是涉及到动态创建的全部释放
    ...
    ...
    ...
    ...free;//凡是涉及到动态创建的全部释放
    end;
    end;
    楼上的,这样不就可以了吗?异常的时候执行finally,不是都释放了吗?
      

  2.   

    你理解错了,try finally并不会捕获异常。要使用 try except
      

  3.   

    没有异常处理,线程直接崩溃,finally块根本执行不到。
      

  4.   

    那改成
    procedure a.Execute;
    begin
    FreeOnTerminate := true;
    try
    .....//其他代码
    ...free;//凡是涉及到动态创建的全部释放
    ...
    ...
    ...
    ...free;//凡是涉及到动态创建的全部释放
    except
    ...free;//凡是涉及到动态创建的全部释放
    ...
    ...
    ...
    ...free;//凡是涉及到动态创建的全部释放
    end;
    end;
    这种就可以了?
      

  5.   

    try
    try
    your code to execute
    except
    your exception handler
    end;
    finally
    something to free
    end;
      

  6.   

    实际上我想不通的是
    try ...exctp
    try ...finally区别仅仅在是否捕获错误,释放语句都一样执行的,应该不是引起我这个问题的原因吧?
      

  7.   

    哪边告诉你异常抛出,线程崩溃了,你finally还能执行的?
      

  8.   

    某些 Create 尽量放在循环外边。
    再找找有没有 Create 没有 Free
    或循环里的 Create 没有 循环 Free
      

  9.   

    在try finally结构块里的语句,无论是抛出异常还是含有Exit语句,finally和end之间的语句都是要执行的。你可以做个测试,很简单的。执行完finally块后才会抛出异常或Exit。
      

  10.   

    对,fianlly不能捕获异常,执行是肯定的。区别在此。
      

  11.   

    唯一会导致fianlly不执行的pascal语句就是halt。嵌入式汇编没测试。
      

  12.   

    Try...finally Statements 
    Sometimes you want to ensure that specific parts of an operation are completed, whether or not the operation is interrupted by an exception. For example, when a routine acquires control of a resource, it is often important that the resource be released, regardless of whether the routine terminates normally. In these situations, you can use a try...finally statement. The following example shows how code that opens and processes a file can ensure that the file is ultimately closed, even if an error occurs during execution: Reset(F);
    try
       ... // process file F
    finally
       CloseFile(F);
    end;
    The syntax of a try...finally statement is try statementList1 finally statementList2 end
    where each statementList is a sequence of statements delimited by semicolons. The try...finally statement executes the statements in statementList1 (the try clause). If statementList1 finishes without raising exceptions, statementList2 (the finally clause) is executed. If an exception is raised during execution of statementList1, control is transferred to statementList2; once statementList2 finishes executing, the exception is re-raised. If a call to the Exit, Break, or Continue procedure causes control to leave statementList1, statementList2 is automatically executed. Thus the finally clause is always executed, regardless of how the try clause terminates. If an exception is raised but not handled in the finally clause, that exception is propagated out of the try...finally statement, and any exception already raised in the try clause is lost. The finally clause should therefore handle all locally raised exceptions, so as not to disturb propagation of other exceptions. 
      

  13.   

    要使用 try except
      

  14.   

    (小蓝鸟贵薪) 人很不错的,呵呵,我知道的。BambooCaep也很热心,回答了我好多问题,谢谢了。
    下面请大家继续讨论问题。
      

  15.   

    这个问题不在于是
    try..except还是try...finally上
    看到网上类似的问题很多,没有1个是回答道满意的。
    目前随便用try..except还是try...finally,内存缓慢增加是事实。请问还有什么原因?
      

  16.   

    bwe2009
    楼主呀,这个可能是你的程序引用多余的代码时没有正确退出时
    就会出现这个问题的,
    其实楼上几位“仁兄”考虑到用这个结构
    try..except还是try...finally上
    是可以参考的,这样可以处理程序的“假死”或者“死循环”的
    不过“逻辑”性的错误处理起来有点难度的............
      

  17.   

    能重现问题所在的问题,很容易调出来啊将线程中,idHTTP操作部分全注释掉,运行,看看内存情况
    如果没有增长,说明idHTTP操作问题
    内存增长,那说明其它问题,如ADO操作或其它
    将ADO操作注释掉,再运行,再检查我很好奇你们是怎么检查内存泄露问题的?难道不是这样检查的吗,除了一些工具外?
      

  18.   

    比如代码:
    MyThread.Execute;
    [
       while not terminated do
       [
          // 1: get data
          count := get_data_from_db_by_ado(datas);
          // 2: do job
          for i := 0 to count - 1 do
            do_my_job_by_idhttp(datas[i]);      sleep(10);
       ]
    ]操作就两部分,1个是get data, 2: do job
    将代码注掉一部分,程序照样跑,问题很快定位,一点点细化,就找出来了。
      

  19.   

    BambooCaep
     (乱拳) 
    我知道你是“猪头”和“杂种”
    还解析什么
      

  20.   

    BambooCaep
     (乱拳)  
    我知道你是“猪头”和“杂种”
    还解析什么
      

  21.   

    BambooCaep
     (乱拳)  
    我知道你是“猪头”和“杂种”
    还解析什么