如何获取Android中对象的内存大小或性能基准? [英] How to get the in-memory size of an object in Android, or performance benchmarks?

查看:1351
本文介绍了如何获取Android中对象的内存大小或性能基准?的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

长话短说,我想测试android.os.Bundle类的克隆实现 针对那个班级,看看哪个更好.我已经知道我的版本可能会更差,但是我想知道多少.有没有适用于Android的基准测试工具,可以用来查看哪个对象的内存更大和/或需要更多的处理时间来存储/检索值?

TL; DR:

我查看了android.os.Bundle类的源代码,但我不喜欢它存储和返回对象的方式.它只是将它们存储在HashMap<String, Object>中,然后使用ClassLoader强制转换为请求的对象的类(例如getString()getInt()).我觉得这或任何与此相关的类转换都违反了类型安全性,并在编程级别引入了歧义,这是静态类型旨在防止的,不是吗?

我想创建一个类似的数据容器类,该类不违反类型安全性并且不引入歧义.逻辑上简单但显然效率低下的方法是为我要存储的每个类都提供一个Map.

我决定的是一个HashMap<String, Integer>,其中包含要存储的每个类的一系列列表的键索引映射.例如,调用getString(String key)将从映射中获取与该键关联的整数索引(如果存在),然后尝试在关联的ArrayList<String>中获取该索引处的对象.

唯一的歧义是返回null(该类的列表中不存在索引)或正确类的错误对象(已映射索引存在,但原始对象与该对象一起存储)键在另一个列表中),这实际上是程序员要检查的责任.

此类的对象只是临时容器,用于以标准化方式将数据从一个地方运送到另一个地方.他们不是要坚持下去.它们也没有以与Bundles相同的方式使用,尽管我想要这样的统一数据容器的部分原因是能够轻松转换为BundleJSONObjectContentValuesCursor然后回来.

也许真正的问题是:真的真的那么糟糕吗?还是我会竭尽全力避免这种情况?我想无论哪种情况,好的编程实际上都是避免歧义的唯一方法.

更新:

看起来Bundle在从Parcel中解包时仅使用Classloader,但每次put()调用都会对unparcel()进行调用.检索时,它只是在ClassCastException的try-catch块中强制转换为方法返回的类型.这可能是最简单的方法.

解决方案

我是否可以使用任何适用于Android的基准测试工具 查看哪个对象在内存中更大和/或需要更多的处理 是时候存储/检索值了吗?

是的,Android为开发人员提供了许多出色的工具,建议您了解它们.这里有正式文档链接,是一个很好的开始.

假设您在Eclipse中,请切换到DDMS透视图.

现在,这些视图应该可以帮助您测量内存:

  • 分配跟踪器..您可以查看哪些对象占用了多少内存.在运行过程中,您必须按开始跟踪"按钮,然后按获取分配"按钮.
  • 堆..您可以查看从堆中获取了多少内存.

要分析您的应用程序,请查看瓶颈等.请使用 Traceview .要从Eclipse方便地调用它,请打开 Threads 视图,然后在运行程序时单击带有红色圆圈的按钮,例如记录按钮".

Long story short, I want to test my clone implementation of the android.os.Bundle class against that class to see which is better. I already know my version is likely going to be worse but I want to know how much worse. Are there any benchmarking tools out there for Android that I can use to see which object is bigger in memory and/or takes more processing time to store/retrieve values?

TL;DR:

I looked at the source code for the android.os.Bundle class, and I don't like how it stores and returns objects. It just stores them in a HashMap<String, Object> and then casts to the requested object's class (like getString() or getInt()) using a ClassLoader. I feel that this, or any class casting for that matter, violates type-safety and introduces ambiguity at the programming level, which is what static typing aims to prevent, is it not?

I want to create a similar data container class that doesn't violate type-safety and doesn't introduce ambiguity. The logically simple yet obviously inefficient way would be to have a Map for each class I want to store.

What I decided on was a single HashMap<String, Integer> that contains key-index mappings for an assortment of Lists for each class I want to store. For example a call to getString(String key) will get the integer index associated with that key from the map if it exists and then try to get the object at that index in the associated ArrayList<String>.

The only ambiguity here would be returning either null (where the index doesn't exist in the List for that class) or the wrong object of the right class (where the mapped index exists but the original object stored with that key is in another List), which is really the programmer's responsibility to check for.

Objects of this class are only temporary containers, used to ship data from one place to another in a standardized fashion. They're not meant to stick around. They're also not used in the same manner as Bundles, although part of the reason I want a unified data container like this is to be able to easily convert to a Bundle, JSONObject, ContentValues or Cursor and back.

Or maybe the real question is: is casting really all that bad, or am I just going to extreme efforts to avoid it? I guess good programming is really the only way to avoid ambiguity in either case.

Update:

It looks like Bundle only uses the Classloader when it's unpacking itself from a Parcel, but it makes a call to unparcel() with every put() call. When retrieving it simply casts to the type that the method returns, inside a try-catch block for ClassCastException. That's probably the simplest way to do it.

解决方案

Are there any benchmarking tools out there for Android that I can use to see which object is bigger in memory and/or takes more processing time to store/retrieve values?

Yes, Android comes with a lot of great tools for developers, it's recommended to get to know them. Here you have official documentation link for a good start.

Switch to DDMS perspective, assuming you are in Eclipse.

Now, these views should be helpful to you in measuring memory:

  • Allocation tracker. You can see which objects take how much memory. During a run you have to press buttons "Start tracking" and later "Get Allocations".
  • Heap. You can see what amount of memory is taken from the heap.

To profile your application, see bottlenecks etc. use Traceview. To call it conveniently from Eclipse open Threads view and while running your program click the button with red circle, like "record button".

这篇关于如何获取Android中对象的内存大小或性能基准?的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

查看全文
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆