0

是否可以像在 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
        }

    }
4

0 回答 0