java 如何在 Android 或性能基准测试中获取对象的内存大小?
声明:本页面是StackOverFlow热门问题的中英对照翻译,遵循CC BY-SA 4.0协议,如果您需要使用它,必须同样遵循CC BY-SA许可,注明原文地址和作者信息,同时你必须将它归于原作者(不是我):StackOverFlow
原文地址: http://stackoverflow.com/questions/14366410/
Warning: these are provided under cc-by-sa 4.0 license. You are free to use/share it, But you must attribute it to the original authors (not me):
StackOverFlow
How to get the in-memory size of an object in Android, or performance benchmarks?
提问by Austin B
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 muchworse. 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?
长话短说,我想针对那个类测试我的 android.os.Bundle 类的克隆实现,看看哪个更好。我已经知道我的版本很可能会更糟糕,但我想知道有多少糟糕。是否有任何适用于 Android 的基准测试工具可以用来查看哪个对象在内存中更大和/或需要更多处理时间来存储/检索值?
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?
我查看了 android.os.Bundle 类的源代码,我不喜欢它存储和返回对象的方式。它只是将它们存储在 a 中HashMap<String, Object>
,然后使用 ClassLoader转换为所请求对象的类(如getString()
或getInt()
)。我觉得这个或任何与此相关的类转换违反了类型安全并在编程级别引入了歧义,这是静态类型旨在防止的,不是吗?
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.
我想创建一个不违反类型安全且不引入歧义的类似数据容器类。逻辑上简单但显然效率低下的方法是为我想要存储的每个类都有一个 Map。
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>
.
我决定选择一个单曲HashMap<String, Integer>
,其中包含我想要存储的每个类的各种列表的键索引映射。例如,调用getString(String key)
将从映射中获取与该键关联的整数索引(如果存在),然后尝试在关联的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.
这里唯一的歧义是返回null
(该类的 List 中不存在索引)或正确类的错误对象(其中映射的索引存在但使用该键存储的原始对象在另一个 List 中) ,这确实是程序员的责任来检查。
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.
此类的对象只是临时容器,用于以标准化方式将数据从一个地方传送到另一个地方。他们不打算留下来。他们也不会以同样的方式为捆绑使用,虽然部分原因我想这样一个统一的数据容器是能够很容易地转换为Bundle
,JSONObject
,ContentValues
或Cursor
和背部。
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.
看起来 Bundle 只在从 Parcel 解包时才使用类加载器,但它会在每次 put() 调用时调用 unparcel()。当检索它时,它简单地转换为该方法返回的类型,在ClassCastException
. 这可能是最简单的方法。
采纳答案by Adam Stelmaszczyk
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?
是否有任何适用于 Android 的基准测试工具可以用来查看哪个对象在内存中更大和/或需要更多处理时间来存储/检索值?
Yes, Android comes with a lot of great tools for developers, it's recommended to get to know them. Here you have official documentation linkfor a good start.
是的,Android 为开发者提供了很多很棒的工具,建议去了解它们。这里有官方文档链接,这是一个良好的开端。
Switch to DDMS perspective, assuming you are in Eclipse.
切换到 DDMS 透视图,假设您在 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 Threadsview and while running your program click the button with red circle, like "record button".
要分析您的应用程序,查看瓶颈等,请使用Traceview。要从 Eclipse 打开Threads视图方便地调用它,并在运行程序时单击带有红色圆圈的按钮,如“记录按钮”。
回答by Nativ
If it's possible to make your object be Serializable(by implementing Serializable interface). Then run the following code. It checks how much bytes your object takes:
如果可以使您的对象可序列化(通过实现 Serializable 接口)。然后运行以下代码。它检查您的对象占用了多少字节:
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;
}
回答by CommonsWare
Are there any benchmarking tools out there for Android that I can use to see which object is bigger in memory
是否有任何适用于 Android 的基准测试工具可以用来查看内存中哪个对象更大
MAT.
垫。
and/or takes more processing time to store/retrieve values?
和/或需要更多的处理时间来存储/检索值?
Traceview.
跟踪视图。
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?
我觉得这个或任何与此相关的类转换违反了类型安全并在编程级别引入了歧义,这是静态类型旨在防止的,不是吗?
Static typing is like a seasoning. How much is the right amount depends upon the taster.
静态类型就像调味料。多少是正确的量取决于品尝者。
回答by Dhruv Gairola
I would recommend MAT (memory analyser tool) too but there are caveats. Know that things like images are not stored in heap memory in certain versions e.g., before honeycomb, images are stored in native memory. Hence, checking the memory may not be very accurate all the time but I would recommend it in your case.
我也会推荐 MAT(内存分析器工具),但有一些警告。知道像图像这样的东西在某些版本中不存储在堆内存中,例如,在蜂窝之前,图像存储在本机内存中。因此,检查内存可能不是一直很准确,但我会在您的情况下推荐它。