DELPHI盒子
!实时搜索: 盒子论坛 | 注册用户 | 修改信息 | 退出
检举帖 | 全文检索 | 关闭广告 | 捐赠
技术论坛
 用户名
 密  码
自动登陆(30天有效)
忘了密码
≡技术区≡
DELPHI技术
lazarus/fpc/Free Pascal
移动应用开发
Web应用开发
数据库专区
报表专区
网络通讯
开源项目
论坛精华贴
≡发布区≡
发布代码
发布控件
文档资料
经典工具
≡事务区≡
网站意见
盒子之家
招聘应聘
信息交换
论坛信息
最新加入: szliyu112358
今日帖子: 52
在线用户: 14
导航: 论坛 -> 移动应用开发 斑竹:flyers,iamdream  
作者:
男 hq200306 (200306) ★☆☆☆☆ -
普通会员
2022/8/8 7:01:13
标题:
Delphi开发安卓app时,如何检测内存泄漏? 浏览:1461
加入我的收藏
楼主: Delphi开发安卓app时,如何检测内存泄漏?有没有检测内存泄漏工具?
----------------------------------------------
-
作者:
男 pcplayer (pcplayer) ★☆☆☆☆ -
普通会员
2022/8/12 0:13:03
1楼: delphi 开发的程序肯定是可以在 WINDOWS 底下跑的啊。

如果你在 WINDOWS 底下没有内存泄漏,到安卓底下就不应该有。

所谓内存泄漏,一般是你创建了个什么东西,没有释放。这种事情,写代码小心一点,应该不容易出现。
----------------------------------------------
-
作者:
男 stacker (OOP才是王道) ★☆☆☆☆ -
普通会员
2022/8/12 2:34:16
2楼: 請愛用try...finally...end
----------------------------------------------
-
作者:
男 newbuyer (newbuyer) ★☆☆☆☆ -
普通会员
2022/8/12 4:39:39
3楼: Android Studio有相应的工具, 但是估计对Delphi是没用针对的是Java,Delphi Windows一般用ReportMemoryLeaksOnShutdown来报告,我现在用的Deleaker还算可以, FastMM听说在MacOS上也可用, Android的我没搞过, 刚才查了下, 看这个有没有用:

https://bitbucket.org/shadow_cs/delphi-leakcheck/src/master/

https://dl.downloadly.ir/Files/Software/Deleaker_2022.6_Downloadly.ir.rar

https://landgraf.dev/en/catching-memory-leaks-in-delphi/

实际上对于没有gc的语言MemLeak是很难根治的(哪怕有gc恶劣的算法/习惯也很容易整垮app),理论上多用try finally/FreeAndNil是可以减轻, 但是的确代码量到一定程度就难以确保. 有的Leak本来就是系统库/Framework产生的(例如Indy), D11刚出来时我就看到两个leaks,一google发现其他人都报告过, 非常容易测试发现的两个bugs, 所以说对EMB公司的质量控制没有信心.
----------------------------------------------
-
作者:
男 emailx45 (emailx45) ▲▲▲▲△ -
普通会员
2022/8/12 4:59:10
3楼: at general, if any "memory leaks" occurrs then "it should be guilt of developer" not necessary from language! of course, if any bug on language it's not guilt from developer!

basic rules:

0) put this command your .DPR file - try catch the "memory leaks" in Delphi - native!!!

ReportMemoryLeaksOnShutdown := true;



1) if you "create" any instance of object, YOU SHOULD RELEASE/FREE!

2) if you use "interfaces", normally, the "garbase collector - GC / ARC technic should take care about it" ... but each case is a new case!!! need study about!

3) always that necessary, use "TRY... FINALLY ... END;". if necessary use "TRY... EXCEPT...END;" nested.

-- NOTE: DONT ABUSE OF THIS USAGE AT ALL PLACES IN YOUR CODE! BE CLEAN! BE PROFESSIONAL!

4) if you dont have certain about if needs "free" or "not free" you instance object.... DO TESTS... with Free or without Free!

if you needs test your code in Posix platfoms, like ANDROID, try this tool:


LeakCheck (Free)  +/- 2 MBytes sources

Delphi LeakCheck is another great option for detecting memory leaks. It’s also free, open source, and has some advantages over FastMM: it’s cross-platform, meaning you can check leaks directly in mobile and Linux applications; and it integrates very well with unit test frameworks (namely DUnit and DUnitX).

The way to get started with it is similar to FastMM: add LeakCheck unit as the first used unit in your dpr uses clause, and it will plugin and be ready to use. Setting up for unit testing is a little more complicated though, but that’s part of the game.

One small disadvantage is that to use it you are almost on your own: the project hasn’t received updates for a while (which isn’t necessarily bad since it’s working).

But that means probably you won’t get much help directly from the author (I never tried, to be fair).

There is also not much information about it in the web, I just found one single article that explains how to use it besides the detailed description in the official Bitbucket repository itself.

Pros
- Free;
- Full source code;
- Cross-plataform;
- Integrates well with unit testing (DUnit and DUnitX).

Cons
- Not much information around about how to use it;
- No recent updates, no official support;

https://bitbucket.org/shadow_cs/delphi-leakcheck


NOTE: dont use it in your commercial software!!! why? because it's not have support!


before all try this:


code:
myInstanceObj : TMyObjectClass;

procedure XXXXX;
var
  myInstanceObj : TMyObjectClass;
begin
// I create, I kill.
myInstanceObj := TMyObjectClass.Create;
try
  try
  ... more code 
  except
    //
    // you can verify the "exception category" if necessary
    //
    On E:EDivideByZero  do  // exception when any number divided by zero =  4/0=???
    begin

    end;
    On E:Exception do   // generic exceptions
    begin
       // what to do with this error?
    end;
    //
    // etc...
  end;
finally
  // usage default:
  myInstanceObj.Free;
  MyInstanceObj := nil; // to avoid access it again in another place... because Delphi dont release the pointer-address by default!
  //
  // in Posix, use:
  // myInstanceObj.DisposeOf;
  // myInstanceObj := nil;
  //
  // using FreeAndNil(...) do the same above in just 1 line
  // FreeAndNil( myInstanceOjb );
end;
----------------------------------------------
The higher the degree, the greater the respect given to the humblest!RAD 11.3
作者:
男 keymark (嬲) ▲▲▲△△ -
普通会员
2022/8/12 10:11:44
4楼: https://valgrind.org/
Valgrind 发行版目前包括七个生产质量工具:一个内存错误检测器、两个线程错误检测器、一个缓存和分支预测探查器、一个生成缓存和分支预测探查器的调用图,以及两个不同的堆探查器。它还包括一个实验性的SimPoint基本块矢量生成器。它运行在以下平台上:X86/Linux、AMD64/Linux、ARM/Linux、ARM64/Linux、PPC32/Linux、PPC64/Linux、PPC64LE/Linux、S390X/Linux、MIPS32/Linux、MIPS64/Linux、X86/Solaris、AMD64/Solaris、ARM/Android(2.3.x 及更高版本)、ARM64/Android、X86/Android(4.0 及更高版本)、MIPS32/Android、X86/FreeBSD、AMD64/FreeBSD、X86/Darwin 和 AMD64/Darwin(Mac OS X 10.12)。
----------------------------------------------
[alias]  co = clone --recurse-submodules  up = submodule update --init --recursiveupd = pullinfo = statusrest = reset --hard懒鬼提速https://www.cctry.com/>http://qalculate.github.io/downloads.htmlhttps://www.cctry.com/
作者:
男 hq200306 (200306) ★☆☆☆☆ -
普通会员
2022/8/12 12:19:06
5楼: @emailx45,我试了leakcheck自带的例程,windows可以提示内存泄露,但android没有任何提示,也找不到所写的日志
----------------------------------------------
-
作者:
男 emailx45 (emailx45) ▲▲▲▲△ -
普通会员
2022/8/12 12:59:28
6楼: hi @hq200306

unit LeakCheck.Report.FileLog.pas

....
{$IF Defined(MACOS) OR Defined(IOS) OR Defined(LEAK_REPORT_DOCUMENTS)}
  BasePath := TPath.GetDocumentsPath;
  BaseName := ExtractFileName(ParamStr(0));
{$ELSEIF Defined(MSWINDOWS)}
  BasePath := ExtractFilePath(ParamStr(0));
  BaseName := ExtractFileName(ParamStr(0));
{$ELSEIF Defined(ANDROID)}
  // Note that this requires Read/Write External Storage permissions
  // Write permissions option is enough, reading will be available as well
  BasePath := '/storage/emulated/0/';
  BaseName := 'LeakCheck_Log';
{$IFEND}
  BasePath := TPath.Combine(BasePath, ChangeFileExt(BaseName, ''));

  FLogFileName := BasePath + '.log';
  FGraphFileName := BasePath + '.dot';
end;
----------------------------------------------
The higher the degree, the greater the respect given to the humblest!RAD 11.3
作者:
男 hq200306 (200306) ★☆☆☆☆ -
普通会员
2022/8/12 15:34:59
7楼: @emailx45 这个LeakCheck.Report.FileLog.pas单元我都看过了,
甚至是把BasePath := '/storage/emulated/0/'改成System.IOUtils.TPath.GetSharedDocumentsPath都没看到生成泄露报告。

@emailx45能不能帮我验证一下,安卓能不能产生泄露报告?
----------------------------------------------
-
作者:
男 emailx45 (emailx45) ▲▲▲▲△ -
普通会员
2022/8/13 2:32:19
8楼: hi @hq200306

basically, in Android platform it's necessary ask "permission" to read/write storage (internal/external "disk")... 

in "Android 11" this is "mandatory" --> app needs explicitly ask the permissions!!! including read/write internal/external "disk" to see files!!! 

then, you need use 2 procedures used by Delphi for FMX Android apps:

// TRequestPermissionsResultEvent = procedure(Sender: TObject; const APermissions: TClassicStringDynArray; const AGrantResults: TClassicPermissionStatusDynArray) of object;
procedure MyRequestPermissionsResult(ASender: TObject; const APermission: TClassicStringDynArray; const AGrantResults: TClassicPermissionStatusDynArray);

// TDisplayRationaleEvent = procedure(Sender: TObject; const APermissions: TClassicStringDynArray; const APostRationaleProc: TProc) of object;
procedure MyDisplayRationale(ASender: TObject; const APermissions: TClassicStringDynArray; const APostRationaleProc: TProc);
    //

here my sample for your tests:


{$IFDEF ANDROID}
  PermissionsService.RequestPermissions(MyArrayPermissions, MyRequestPermissionsResult);
  //
  if PermissionsService.IsEveryPermissionGranted(MyArrayPermissions) then
  begin
    GetMyDirectories;
  end
  else
    TDialogService.ShowMessage('This permissions ("ReadStorage" and "WriteStorage") is necessary for this task!');
{$ELSE}
  GetMyDirectories;
{$ENDIF}
此帖子包含附件:emailx45_202281323219.zip 大小:14.0K
----------------------------------------------
The higher the degree, the greater the respect given to the humblest!RAD 11.3
作者:
男 hq200306 (200306) ★☆☆☆☆ -
普通会员
2022/8/13 9:30:29
9楼: 谢谢emailx45,现在可以测出安卓内存的泄露问题了
----------------------------------------------
-
作者:
男 hq200306 (200306) ★☆☆☆☆ -
普通会员
2022/8/13 10:02:56
10楼: 1、试了几个程序,LeakCheck安卓下能测出内存泄露,仅是报了类中的字符串内存泄露,而不是整个类的实例。

2、delphi的几个系统类库没有释放
Leak detected B82391B0 size 32 B for UnicodeString {RefCount: 2} = MVPMatrix
Leak detected B8239930 size 30 B for UnicodeString {RefCount: 2} = texture0
Leak detected B8241130 size 32 B for UnicodeString {RefCount: 2} = MVPMatrix

估计LeakCheck不太完善
----------------------------------------------
-
信息
登陆以后才能回复
Copyright © 2CCC.Com 盒子论坛 v3.0.1 版权所有 页面执行62.5毫秒 RSS