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:每个意图/活动的堆大小是多少?的主要内容,如果未能解决你的问题,请参考以下文章