如何衡量Android应用程序数据大小和识别存储泄漏?

我做了一个小的Android应用程序,并已经使用了一段时间了。 我注意到,在设置中,我的应用程序的特征(我不想分析“应用程序”行或“caching”行上显示的数量感兴趣的“数据”行),它显示约20 MB,其中对我来说似乎很多。 我恐怕应用程序有存储泄漏(即它产生的数据,永远不会被擦除)。

我决定调查和衡量可能会占用那么多空间的东西。 我使用几乎所有可用的存储选项为这个应用程序:SQLite数据库,内部文件,外部文件,共享偏好(和caching文件,包括Glide图片加载)。

到目前为止,由于SQLite数据库的问题 ,我发现我的DB文件大约需要500 kB。 我发现通过recursion扫描文件夹getFilesDir()中的文件和文件夹,我在内部和应用程序专用外部文件中使用10 kB数据。 我还没有分析共享首选项的大小,但我存储less于20个键/值对。

探索文件夹getCacheDirs()我还发现,Glide使用大约3 MB的caching(接近Android设置应用程序告诉)。

我的问题是,哪个导致我想念find这个19.5 MB的数据,我无法find? 我忘了某种可能占用空间的存储吗? 而且,更一般地说,有没有工具可以分析存储泄漏(即应用程序产生的数据可能永远不会被删除)?

Solutions Collecting From Web of "如何衡量Android应用程序数据大小和识别存储泄漏?"

没有存储泄漏。

你没有计算odex (dalvik)或oat (android运行时)文件。它们通常位于

 /data/dalvik-cache/xxx.odex /data/dalvik-cache/<target-architecture>/xxx.oat 

这些文件是由系统生成的在安装期间优化的。

此外,你没有指望你的APK文件位于

 /data/app/xxx.yyy.zzz.apk 

如果设备没有根目录,则目录或文件不能从adb shell访问。

我认为在设置中的存储使用情况显示包括以下三个部分

 /data/data/xxx.yyy.zzz /data/app/xxx.yyy.zzz.apk odex or oat file 

因此,您在/data/data/xxx.yyy.zzz下计算的存储大小始终小于设置中的总大小。

您可以使用MAT TOOL来优化应用程序中的内存/大小问题。它会使用更多的内存来显示应用程序中的哪个部分。

Android工作室运行你的应用程序,并转到工具 – > Android-> AndroidDeviceMonitor ,运行你的scheme,并在设备监视器点击下载你的应用程序.hprof文件 下载.hprof文件

之后,您需要通过在sdk-> platform-tools中使用hprof-conv.exe将Android-studio .hprof文件转换为Eclipse Mat支持的.hprof文件,然后按照CMD Promt中的cmd

 F:\Android_Studio_SDK\platform-tools>hprof-conv "C:\Users\Bala\Desktop\your_AS_file.hprof" "C:\Users\Bala\Desktop\MAT_File_Name.hprof" 

并在MAT工具文件 – > OpenHeapDump打开你的.hprof文件,它会显示你的应用程序内存利用包,类,object..etc;

了解MAT工具的一些推荐链接
链接1
链接2

在@James的build议之后,我开始探索不同的文件夹,在和一个同事讨论这个问题并试图探索许多文件夹之后,我终于发现大部分数据来自于我以前的Webview的caching。 我发布了我的所有调查,希望这会有所帮助。

我在应用程序启动时执行以下代码,从我的主要活动中调用analyseStorage(this)

 public void analyseStorage(Context context) { long totalSize = 0; File appBaseFolder = context.getFilesDir().getParentFile(); for (File f: appBaseFolder.listFiles()) { if (f.isDirectory()) { long dirSize = browseFiles(f); totalSize += dirSize; Log.d(STORAGE_TAG, f.getPath() + " uses " + dirSize + " bytes"); } else { totalSize += f.length(); } } Log.d(STORAGE_TAG, "App uses " + totalSize + " total bytes"); } private long browseFiles(File dir) { long dirSize = 0; for (File f: dir.listFiles()) { dirSize += f.length(); //Log.d(STORAGE_TAG, dir.getAbsolutePath() + "/" + f.getName() + " weighs " + f.length()); if (f.isDirectory()) { dirSize += browseFiles(f); } } return dirSize; } 

重要的是要特别扫描context.getFilesDir().getParentFile() ,它与文件夹/data/data/my.app.package/

执行该代码后,我有以下日志:

 D/storage﹕ /data/data/my.app.package/lib uses 0 bytes D/storage﹕ /data/data/my.app.package/cache uses 3371773 bytes D/storage﹕ /data/data/my.app.package/databases uses 483960 bytes D/storage﹕ /data/data/my.app.package/shared_prefs uses 604 bytes D/storage﹕ /data/data/my.app.package/app_webview uses 9139469 bytes D/storage﹕ /data/data/my.app.package/files uses 7723 bytes D/storage﹕ /data/data/my.app.package/app_ACRA-approved uses 0 bytes D/storage﹕ /data/data/my.app.package/app_ACRA-unapproved uses 0 bytes D/storage﹕ App uses 13003529 total bytes 

我能看到的是:

  • caching只用于Glide的图片加载,需要3MB
  • SQLite数据库需要500kB
  • 共享偏好需要600B
  • 我曾经用过的所有Webviews的caching仍然需要9MB
  • 其余的文件,在files和其他文件夹下,大多数是由ACRA用于错误跟踪,并采取10kB

最后,我终于发现,我的大部分数据都进入了Webviewcaching,实际上并没有被显式地存储为caching。 我删除了这些文件,实际上将我的应用程序的大小减less了20MB,甚至比上面列出的还多。 我现在知道我的应用程序的数据量是多less。

您可以使用像Leak Canary这样的库来自动检测应用程序中的所有内存泄漏: https : //corner.squareup.com/2015/05/leak-canary.html

您也可以转到Android Studio中的DDMS,并在您的应用程序中获取有关存储的更多信息,而无需编码任何内容。 然而,大部分泄漏将由泄漏金丝雀检测到。

希望能帮助到你!