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

Vin*_*nce 10 sqlite storage android caching

我制作了一个小型Android应用程序并且已经使用了一段时间了.我注意到,在设置中,我应用程序特征的"数据"行(我对分析"应用程序"行和"缓存"行上显示的数量不感兴趣),它显示大约20 MB,其中对我来说似乎很重要.我担心应用程序存在泄漏(即它产生的数据永远不会被删除).

我决定调查和衡量可能占用那么多空间的东西.我几乎使用了这个应用程序的所有可用存储选项:SQLite DB,内部文件,外部文件,共享首选项(以及包括Glide图片加载的缓存文件).

到目前为止,由于有关SQLite DB的问题,我发现我的DB文件大约需要500 kB.我通过递归扫描文件和文件夹找到getFilesDir()了我在内部和app-private外部文件中使用10 kB数据的文件和文件夹.我还没有分析共享首选项大小,但我存储少于20个键/值对.

探索文件夹getCacheDirs()我还发现Glide使用大约3 MB的缓存(接近Android设置应用程序所说的).

我的问题是,哪些导致我错过了找到这个19.5 MB的数据我找不到的位置?我忘记了某种可能占用空间的存储空间吗?而且,更一般地说,是否有工具来分析存储泄漏(即应用程序产生的数据可能永远不会被删除)?

Vin*_*nce 6

按照@James的建议,我开始探索不同的文件夹,在与同事讨论问题并尝试探索许多文件夹之后,我终于发现大部分数据来自我以前的Webview的缓存.我发布了所有的调查,希望它会有所帮助.

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

public void analyseStorage(Context context) {
  File appBaseFolder = context.getFilesDir().getParentFile();
  long totalSize = browseFiles(appBaseFolder);
  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() + " uses " + f.length() + " bytes");
    if (f.isDirectory()) {
      dirSize += browseFiles(f);
    }
  }
  Log.d(STORAGE_TAG, dir.getAbsolutePath() + " uses " + dirSize + " bytes");
  return dirSize;
}
Run Code Online (Sandbox Code Playgroud)

重要的是要专门扫描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
Run Code Online (Sandbox Code Playgroud)

我能看到的是:

  • 仅由Glide用于图片加载的缓存需要3MB
  • SQLite数据库需要500kB
  • 共享首选项需要600B
  • 我以前所有Webview的缓存仍然需要9MB
  • 其余文件,files以及其他文件夹,主要由ACRA用于错误跟踪并占用10kB

最后,我终于发现我的大部分数据都转到了Webview缓存,实际上并没有明确存储为缓存.我删除了这些文件,它实际上减少了我的应用程序的大小20MB,甚至超过上面列出的.我现在知道我的应用程序数据的数量级.


ali*_*dro 6

没有存储泄漏.

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

/data/dalvik-cache/xxx.odex
/data/dalvik-cache/<target-architecture>/xxx.oat
Run Code Online (Sandbox Code Playgroud)

这些文件由系统生成,以便在安装期间进行优化.

你也没有计算你所在的APK文件

/data/app/xxx.yyy.zzz.apk
Run Code Online (Sandbox Code Playgroud)

如果设备未植根,则无法从adb shell访问目录或文件.

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

/data/data/xxx.yyy.zzz
/data/app/xxx.yyy.zzz.apk
odex or oat file
Run Code Online (Sandbox Code Playgroud)

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