Android:每个意图/活动的堆大小是多少?

Posted

技术标签:

【中文标题】Android:每个意图/活动的堆大小是多少?【英文标题】:Android: what is the heap size per intent/activity? 【发布时间】: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) - 一点都不实用:-) 【参考方案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。谈话是关于观众和性能的。

【讨论】:

以上是关于Android:每个意图/活动的堆大小是多少?的主要内容,如果未能解决你的问题,请参考以下文章

android 作物活动只能通过意图?

我怎样才能在android中实现wifi直接活动?

Android:如何在运行时增加堆大小?

在android中通过意图传递数据

android

不同Android设备的堆大小[重复]