Java 如何在Android中获取对象的内存大小或性能基准?

Java 如何在Android中获取对象的内存大小或性能基准?,java,android,oop,Java,Android,Oop,长话短说,我想测试我的android.os.Bundle类的克隆实现 来看看哪个更好。我已经知道我的版本可能会更糟,但我想知道有多糟。有没有针对Android的基准测试工具,我可以用来查看哪个对象的内存更大和/或需要更多的处理时间来存储/检索值 TL;博士: 我查看了android.os.Bundle类的源代码,我不喜欢它存储和返回对象的方式。它只是将它们存储在HashMap中,然后使用类加载器强制转换到请求对象的类(如getString()或getInt())。我觉得这或者任何类型转换都违反了

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

TL;博士:

我查看了android.os.Bundle类的源代码,我不喜欢它存储和返回对象的方式。它只是将它们存储在
HashMap
中,然后使用类加载器强制转换到请求对象的类(如
getString()
getInt()
)。我觉得这或者任何类型转换都违反了类型安全,并在编程级别引入了歧义,这正是静态类型化所要防止的,不是吗

我想创建一个类似的数据容器类,它不会违反类型安全性,也不会引入歧义。逻辑上简单但明显低效的方法是为我要存储的每个类都有一个映射

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

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

此类对象只是临时容器,用于以标准化方式将数据从一个地方传送到另一个地方。他们不应该呆在这里。它们的使用方式也不同于Bundle,尽管我想要这样一个统一的数据容器的部分原因是能够轻松地转换为
Bundle
JSONObject
ContentValues
Cursor
并返回

或者,真正的问题是:演员阵容真的那么糟糕吗,或者我只是为了避免它而付出了极大的努力?我想无论哪种情况,好的编程都是避免歧义的唯一方法

更新:

看起来Bundle只在从包中解包时使用类加载器,但它在每次put()调用时都会调用unparcel()。当检索它时,只需在
ClassCastException
的try-catch块中强制转换为方法返回的类型。这可能是最简单的方法

有没有针对Android的基准测试工具,我可以用来查看哪个对象在内存中更大

垫子

和/或需要更多的处理时间来存储/检索值

Traceview

我觉得这或者任何类型转换都违反了类型安全,并在编程级别引入了歧义,这正是静态类型化所要防止的,不是吗

静态打字就像调味品。正确的量是多少取决于品尝者。

我也推荐MAT(内存分析器工具),但有一些注意事项。要知道,在某些版本中,像图像这样的东西不会存储在堆内存中,例如,在蜂窝之前,图像存储在本机内存中。因此,检查内存可能不是一直都很准确,但我建议您这样做

有没有适合Android的基准测试工具我可以使用 查看哪个对象在内存中更大和/或需要更多处理 存储/检索值的时间

是的,Android为开发者提供了很多很棒的工具,建议大家去了解它们。这里有一个良好开端的官方文件

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

现在,这些视图应该有助于您测量内存:

  • 分配跟踪器。您可以查看哪些对象占用了多少内存。在跑步过程中,您必须按“开始跟踪”按钮,然后按“获取分配”
  • 堆。您可以查看从堆中获取的内存量

要评测应用程序,请参阅瓶颈等。使用Traceview。要方便地从Eclipse中调用它,请打开线程视图,并在运行程序时单击带有红色圆圈的按钮,如“录制按钮”。

如果可以使对象可序列化(通过实现可序列化接口)。然后运行以下代码。它检查对象占用的字节数:

private byte[] getBytes(Object o) {
    ByteArrayOutputStream bos = new ByteArrayOutputStream();
    ObjectOutput out = null;
    try {
        out = new ObjectOutputStream(bos);
        out.writeObject(o);
        return bos.toByteArray();
    } catch (IOException e) {
        e.printStackTrace();
    } finally {
        try {
            if (out != null) {
                out.close();
            }
        } catch (IOException ex) {
            // ignore close exception
        }
        try {
            bos.close();
        } catch (IOException ex) {
            // ignore close exception
        }
    }
    return null;
}

如果我尝试位图:“java.io.notserializableeexception:android.graphics.bitmap”@Sabish。我在问题的主体中写到,对象应该是可序列化的,所以我不明白你为什么否决它。ps-只需将对象序列化即可。在大多数情况下,需要注意的是对象必须是可序列化的。。。停止无用的向下投票。这将是资源密集型的,并且不能保证对象的序列化形式将等于VM堆中对象的大小。