【问题标题】:Android: what is the heap size per intent/activity?Android:每个意图/活动的堆大小是多少?
【发布时间】:2013-03-16 09:10:27
【问题描述】:

众所周知,Android 应用程序的 VM 堆大小是有限的。 (主要是 16、24、32、48 或 64 MB RAM,具体取决于硬件)

我们可以得到实际的堆大小

ActivityManager am = (ActivityManager)this.getSystemService(ACTIVITY_SERVICE);
Toast.makeText(this, "HEAP SIZE: " + am.getMemoryClass() + "MB", 1).show();

.

但是,如果我打开一个新的 Intent,内存策略是什么???:

Intent intent = new Intent(MainActivity.this, NewActivity.class);
MainActivity.this.startActivity(intent);

这个新活动是否获得了完整的堆大小并且旧活动在后台保持,并且它的内存被缓存?

或者意图获得一个全新的虚拟机?

我有一个内存非常密集的应用程序,其中大量填充了 Grid- 和 ListViews。 从 Android 3.0 开始,位图是在堆内分配的,这会导致很多令人头疼的问题和 OutOfMemory 错误的麻烦……我想知道我是否可以在它们自己的 Intent 中超越内存饥饿的视图。

【问题讨论】:

  • 一个应用的所有活动共享同一个堆。如果您想外包它,您的 Activity 必须在不同的应用程序中(不同的包名称,并且还单独上传到 Play) - 一点都不实用:-)

标签: android android-listview out-of-memory heap-memory android-gridview


【解决方案1】:

每个进程都有一个堆,无论设备指定大小(如果设备上安装了 Google Play,则至少 16 MB)。

您的应用的所有组件都必须在此堆中运行,因为您的应用是一个进程。所以你所有的活动、服务、广播接收器共享同一个堆。

当您启动一个新 Activity 时,您之前的 Activity 会被推送到后台。因此,它的onPause() 被调用,如果需要,您应该使用该方法释放内存(删除加载的位图等)。

另外,outsorce the memory hungry Views in their own Intents 没有任何意义,因为 Intent 用于启动应用程序组件,如活动和服务。您不能将视图与意图一起使用。相反,您应该缩放位图并仅加载所需的大小,并使用延迟加载等技术来确保内存中的位图不会超过所需的大小。

【讨论】:

  • 当用户回到上一个活动时,位图会发生什么?因为你在 onPause 中提到你删除了加载的位图。
  • @Raghunandan 好吧,然后你在 onResume() 中重新加载它们
  • 在它们自己的 Intents 中超越内存饥饿的视图。我不明白问题的那一部分。所有对象都存储在堆中,并且 gc 确实标记了一次扫描。
【解决方案2】:

我同意 Raghav Sood 的观点。我添加了更多关于如何在列表视图或网格视图中显示图像的内容。

我使用通用图像加载器在列表视图中显示大量图像。

您应该在不使用时回收位图。

http://www.youtube.com/watch?v=_CruQY55HOk。讨论是关于内存管理和内存泄漏以及如何避免它。如果您遇到内存泄漏,您可以使用 MAT Analyzer 来查找内存泄漏。该视频还讨论了使用 MAT Analyzer 并演示了如何消除内存泄漏。

当您在列表视图中显示图像时,您需要回收视图。可见的视图不会被回收。

要在 gridview 或 listview 中显示图像,您可以使用通用图像加载器。延迟加载的改进版本。图像被缓存。您可以在本地或从服务器显示图像。

https://github.com/nostra13/Android-Universal-Image-Loader

 File cacheDir = StorageUtils.getOwnCacheDirectory(context, "your folder");

 // Get singletone instance of ImageLoader
 imageLoader = ImageLoader.getInstance();
 // Create configuration for ImageLoader (all options are optional)
 ImageLoaderConfiguration config = new ImageLoaderConfiguration.Builder(a)
      // You can pass your own memory cache implementation
     .discCache(new UnlimitedDiscCache(cacheDir)) // You can pass your own disc cache implementation
     .discCacheFileNameGenerator(new HashCodeFileNameGenerator())
     .enableLogging()
     .build();
 // Initialize ImageLoader with created configuration. Do it once.
 imageLoader.init(config);
 options = new DisplayImageOptions.Builder()
 .showStubImage(R.drawable.stub_id)//display stub image
 .cacheInMemory()
 .cacheOnDisc()
 .displayer(new RoundedBitmapDisplayer(20))
 .build();

在你的 getView() 中

 ImageView image=(ImageView)vi.findViewById(R.id.imageview); 
 imageLoader.displayImage(imageurl, image,options);//provide imageurl, imageview and options

您可以配置其他选项以满足您的需求。

与通用图像加载器一起,您可以查看支架以实现平滑滚动和性能。 http://developer.android.com/training/improving-layouts/smooth-scrolling.html.

http://www.youtube.com/watch?v=wDBM6wVEO70。谈话是关于观众和性能的。

【讨论】:

    猜你喜欢
    • 2019-10-20
    • 1970-01-01
    • 2013-03-02
    • 2010-12-07
    • 2012-09-19
    • 1970-01-01
    • 1970-01-01
    • 2014-01-11
    • 2014-03-06
    相关资源
    最近更新 更多