RamUsageEstimator,maven坐标:
<dependency>
<groupId>org.apache.lucene</groupId>
<artifactId>lucene-core</artifactId>
<version>4.0.0</version>
</dependency>
RamUsageEstimator就是根据java对象在堆内存中的存储格式,
通过计算Java对象头、实例数据、引用等的大小,相加而得,如果有引用,还能递归计算引用对象的大小。
RamUsageEstimator的源码并不多,几百行,清晰可读。这里不进行一一解读了。
它在初始化的时候会根据当前JVM运行环境、CPU架构、运行参数、是否开启指针压缩、JDK版本等综合计算对象头的大小,而实例数据部分则按照java基础数据类型的标准大小进行计算。
思路简单,同时也在一定程度上反映出了Java对象格式的奥秘!
import java.util.List;
import java.util.concurrent.atomic.AtomicLong;
import lombok.extern.slf4j.Slf4j;
import org.apache.lucene.util.RamUsageEstimator;
import reactor.fn.tuple.Tuple2;
import reactor.fn.tuple.Tuple3;
/* *
* * Starry Starry Night
* * __ __
* * \/---\/
* * ). .(
* * ( (") )
* * ) (
* * / \
* * ( )``
* * ( \ /-\ / )
* * w'W W'w
* *
* author 杨春炼
* email qdcccc@gmail.com
* date 2018-08-24
*
*/
@Slf4j
public class ObjectUtil {
public static Tuple3<Long, Long, String> size(Object o) {
//计算指定对象本身在堆空间的大小,单位字节
long shallowSize = RamUsageEstimator.shallowSizeOf(o);
//计算指定对象及其引用树上的所有对象的综合大小,单位字节
long size = RamUsageEstimator.sizeOf(o);
//计算指定对象及其引用树上的所有对象的综合大小,返回可读的结果,如:2KB
String humanSize = RamUsageEstimator.humanSizeOf(o);
return Tuple3.of(shallowSize, size, humanSize);
}
// public static void main(String[] args) {
// Tuple3<Long, Long, String> size = size(Tuple3.of(1, 1, ""));
// System.out.println(size);
// }
public static Long multiSize(List<Tuple2<Object, Long>> object2Size) {
AtomicLong memAll = new AtomicLong();
object2Size.forEach(t -> {
Object object = t.getT1();
Long size = t.getT2();
if (object == null
|| size == null
|| size == 0) {
return;
}
long l = RamUsageEstimator.shallowSizeOf(object);
long mem = l * size;
memAll.addAndGet(mem);
});
return memAll.get();
}
// public static void main(String[] args) {
// ATest a = ATest.builder().a("1").build();
// BTest b = BTest.builder().a("1").b(1).c(newArrayList(1L, 2L, 3L, 4L, 5L, 6L)).build();
// List<Tuple2<Object, Long>> calculate = newArrayList();
// calculate.add(Tuple2.of(a, 10L));
// calculate.add(Tuple2.of(b, 100L));
// Long aLong = multiSize(calculate);
// System.out.println(aLong);
// }
}
//@Builder
//class ATest {
//
// private String a;
//
//}
//
//@Builder
//class BTest {
//
// private String a;
// private Integer b;
// private List<Long> c;
//}
来源:oschina
链接:https://my.oschina.net/u/2700824/blog/1933652