是否可以像在 c++ 中使用 sizeOf() 一样获取对象的内存消耗?
对于对象是 Parcelable 的,似乎这个可以获取原始字节,不确定它对于该 Parcelable 对象的大小是否准确:
fun marshall(parceable: Parcelable): ByteArray {
val parcel = Parcel.obtain()
parceable.writeToParcel(parcel, 0)
val bytes = parcel.marshall()
parcel.recycle()
return bytes
}
有什么建议吗?
更新:
感谢@Gustavo Passini 品脱与很多方法的链接。有人需要 java.lang.instrument 包但无法在 Android 上使用,找到了一个但需要 api level 26 以上,转换为 koltin 并复制到这里作为 ref (感谢 Agnius Vasiliauskas),它准确吗?:
import java.io.ByteArrayOutputStream
import java.io.ObjectOutputStream
import java.io.Serializable
@TargetApi (26)
object ObjectSizeCalculator {
private fun getFirstObjectReference(o: Any): Any? {
val objectType = o.javaClass.typeName
if (objectType.substring(objectType.length - 2) == "[]") {
try {
return if (objectType == "java.lang.Object[]")
(o as Array<Any>)[0]
else if (objectType == "int[]")
(o as IntArray)[0]
else
throw RuntimeException("Not Implemented !")
} catch (e: IndexOutOfBoundsException) {
return null
}
}
return o
}
fun getObjectSizeInBytes(o: Any?): Int {
val STRING_JAVA_TYPE_NAME = "java.lang.String"
if (o == null)
return 0
val objectType = o.javaClass.typeName
val isArray = objectType.substring(objectType.length - 2) == "[]"
val objRef = getFirstObjectReference(o)
if (objRef != null && objRef !is Serializable)
throw RuntimeException("Object must be serializable for measuring it's memory footprint using this method !")
try {
val baos = ByteArrayOutputStream()
val oos = ObjectOutputStream(baos)
oos.writeObject(o)
oos.close()
val bytes = baos.toByteArray()
var i = bytes.size - 1
var j = 0
while (i != 0) {
if (objectType !== STRING_JAVA_TYPE_NAME) {
if (bytes[i].toInt() == 112)
return if (isArray)
j - 4
else
j
} else {
if (bytes[i].toInt() == 0)
return j - 1
}
i--
j++
}
} catch (e: Exception) {
return -1
}
return -1
}
}