精华内容
下载资源
问答
  • JAVA对象所占内存大小计算例子,博文地址:http://blog.csdn.net/u012787710/article/details/53164226
  • Java对象占用堆内存大小计算

    千次阅读 2019-11-27 17:57:40
    最近看hbase源码,里面有对象占用内存大小的计算。正好笔记记录一下。 一般来说,int占4个字节,long占8个字节,等等。但是对象在队中的存储不止其包含的字段所占用的空间,还包括对象头,对齐填充等信息。接下来...

    欢迎关注本人公众号

    在这里插入图片描述

    概述

    最近在看hbase源码,里面有对象占用内存大小的计算。正好笔记记录一下。

    一般来说,int占4个字节,long占8个字节,等等。但是对象在堆中的存储不止其包含的字段所占用的空间,还包括对象头,对齐填充等信息。接下来就结合hbase源码分析一下对象在堆中的存储情况。

    原生类型(primitive type)的内存占用

    类型占用空间
    boolean在数组中占1个字节,单独使用时占4个字节
    byte1
    short2
    char2
    int4
    float4
    long8
    double8

    boolean占用内存空间说明

    《Java虚拟机规范》一书中的描述:“虽然定义了boolean这种数据类型,但是只对它提供了非常有限的支持。在Java虚拟机中没有任何供boolean值专用的字节码指令,Java语言表达式所操作的boolean值,在编译之后都使用Java虚拟机中的int数据类型来代替,而boolean数组将会被编码成Java虚拟机的byte数组,每个元素boolean元素占8位”。这样我们可以得出boolean类型占了单独使用是4个字节,在数组中又是1个字节。

    那虚拟机为什么要用int来代替boolean呢?为什么不用byte或short,这样不是更节省内存空间吗。大多数人都会很自然的这样去想,我同样也有这个疑问,经过查阅资料发现,使用int的原因是,对于当下32位的处理器(CPU)来说,一次处理数据是32位(这里不是指的是32/64位系统,而是指CPU硬件层面),具有高效存取的特点。

    另外也解决了伪共享问题,boolean类型的数据不会因为占用空间小而与其他数据类型的数据一起使用,注意这一点是我个人的一个猜测。欢迎来辩。

    对象分布基本概念

    如图,java对象在内存中占用的空间分为3类,

    1. 对象头(Header);
    2. 实例数据(Instance Data);
    3. 对齐填充(Padding)。

    而我们常说的基础数据类型大小主要是指第二类实例数据。

    在这里插入图片描述

    对象头

    上图中可以看到,对象头分为三个部分:

    1. Mark Word
    2. 指向类的指针
    3. 数组长度(只有数组对象才有)

    Mark Word

    Mark Word记录了对象和锁有关的信息,当这个对象被synchronized关键字当成同步锁时,围绕这个锁的一系列操作都和Mark Word有关。

    Mark Word在32位JVM中的长度是32bit,在64位JVM中长度是64bit。

    Mark Word在不同的锁状态下存储的内容不同,在32位JVM中是这么存的:


    其中无锁和偏向锁的锁标志位都是01,只是在前面的1bit区分了这是无锁状态还是偏向锁状态。

    JDK1.6以后的版本在处理同步锁时存在锁升级的概念,JVM对于同步锁的处理是从偏向锁开始的,随着竞争越来越激烈,处理方式从偏向锁升级到轻量级锁,最终升级到重量级锁。

    JVM一般是这样使用锁和Mark Word的:

    1,当没有被当成锁时,这就是一个普通的对象,Mark Word记录对象的HashCode,锁标志位是01,是否偏向锁那一位是0。

    2,当对象被当做同步锁并有一个线程A抢到了锁时,锁标志位还是01,但是否偏向锁那一位改成1,前23bit记录抢到锁的线程id,表示进入偏向锁状态。

    3,当线程A再次试图来获得锁时,JVM发现同步锁对象的标志位是01,是否偏向锁是1,也就是偏向状态,Mark Word中记录的线程id就是线程A自己的id,表示线程A已经获得了这个偏向锁,可以执行同步锁的代码。

    4,当线程B试图获得这个锁时,JVM发现同步锁处于偏向状态,但是Mark Word中的线程id记录的不是B,那么线程B会先用CAS操作试图获得锁,这里的获得锁操作是有可能成功的,因为线程A一般不会自动释放偏向锁。如果抢锁成功,就把Mark Word里的线程id改为线程B的id,代表线程B获得了这个偏向锁,可以执行同步锁代码。如果抢锁失败,则继续执行步骤5。

    5,偏向锁状态抢锁失败,代表当前锁有一定的竞争,偏向锁将升级为轻量级锁。JVM会在当前线程的线程栈中开辟一块单独的空间,里面保存指向对象锁Mark Word的指针,同时在对象锁Mark Word中保存指向这片空间的指针。上述两个保存操作都是CAS操作,如果保存成功,代表线程抢到了同步锁,就把Mark Word中的锁标志位改成00,可以执行同步锁代码。如果保存失败,表示抢锁失败,竞争太激烈,继续执行步骤6。

    6,轻量级锁抢锁失败,JVM会使用自旋锁,自旋锁不是一个锁状态,只是代表不断的重试,尝试抢锁。从JDK1.7开始,自旋锁默认启用,自旋次数由JVM决定。如果抢锁成功则执行同步锁代码,如果失败则继续执行步骤7。

    7,自旋锁重试之后如果抢锁依然失败,同步锁会升级至重量级锁,锁标志位改为10。在这个状态下,未抢到锁的线程都会被阻塞。

    指向类的指针

    该指针在32位JVM中的长度是32bit,在64位JVM中长度是64bit。

    Java对象的类数据保存在方法区(java8以后在元数据区)。

    数组长度

    只有数组对象保存了这部分数据。

    该数据在32位和64位JVM中长度都是32bit。

    实例数据

    我们在java类中定义的属性。

    对齐填充

    HotSpot的对齐方式为8字节对齐。
    8字节填充的含义也就是不足8字节(或8字节的倍数)则将其填充至8字节(或8字节的倍数,这里指的是大于当前值的最小一个8的倍数)。如:

    原始长度8字节对齐后长度
    68
    78
    88
    916
    1016

    我们来看一下hbase的计算对齐填充后长度的算法:

    /**
     * Aligns a number to 8.
     * @param num number to align to 8
     * @return smallest number >= input that is a multiple of 8
     */
    public long align(long num) {
      //The 7 comes from that the alignSize is 8 which is the number of bytes
      //stored and sent together
      return  ((num + 7) >> 3) << 3;//将数字加7后抹0(后3位0)
    }
    

    这里采用的是二进制位运算算法,位运算在计算机内是性能最高的算法,所以在阅读开源软件时,会大量看到二进制位运算。

    8字节填充的长度计算其实很简单,将数值先转为2进制,然后将倒数第四位置为1,如果本来是1则不变。然后将后三位置为0即可。

    以26为例,26的二进制表述为11010,那么如何才能将倒数第四位置为1呢?上面算法中加上7,即可以完成进位操作,7是比8小的最大的一个数,二进制是111。然后进位操作以后,如何清除后面的三位置为0呢?简单,右移3位在左移3位即可完成。这也就是上述算法的实现原理。

    指针压缩

    不压缩时指针占8字节。在64位开启指针压缩的情况下 -XX:+UseCompressedOops,存放Class指针的空间大小是4字节。

    对象头占用空间总结

    1. 在32位系统下,存放Class指针的空间大小是4字节,MarkWord是4字节,对象头为8字节。
    2. 在64位系统下,存放Class指针的空间大小是8字节,MarkWord是8字节,对象头为16字节。
    3. 在64位开启指针压缩的情况下 -XX:+UseCompressedOops,存放Class指针的空间大小是4字节,MarkWord是8字节,对象头为12字节。
    4. 如果对象是数组,那么额外增加4个字节。

    hbase源码分析–对象占用空间计算

    这里先简单介绍一下下面示例的背景。
    以hbase 读取wal日志文件输出为例,里面计算了对象占用堆内存大小情况(里面的total_size_sum和edit heap size就是指对象占用空间的就算结果):

    {
    	"sequence": 15,
    	"region": "c06475acdfec83fd5a6bf6d06c796bd1",
    	"actions": [
    		{
    			"qualifier": "HBASE::FLUSH",
    			"vlen": 103,
    			"row": "\\x00",
    			"family": "METAFAMILY",
    			"value": "\\x08\\x00\\x12\\x02t2\\x1A c06475acdfec83fd5a6bf6d06c796bd1 \\x0E*\\x06\\x0A\\x010\\x12\\x01023t2,,1574775527767.c06475acdfec83fd5a6bf6d06c796bd1.",
    			"timestamp": 1574840582064,
    			"total_size_sum": 200
    		}
    	],
    	"table": {
    		"name": "dDI=",
    		"nameAsString": "t2",
    		"namespace": "ZGVmYXVsdA==",
    		"namespaceAsString": "default",
    		"qualifier": "dDI=",
    		"qualifierAsString": "t2",
    		"systemTable": false,
    		"nameWithNamespaceInclAsString": "default:t2"
    	}
    }
    edit heap size: 240
    position: 283
    

    给出对象的java代码:

    public class KeyValue implements ExtendedCell, Cloneable {
    	protected byte [] bytes = null;  // an immutable byte array that contains the KV
    	protected int offset = 0;  // offset into bytes buffer KV starts at
    	protected int length = 0;  // length of the KV starting from offset.
    	private long seqId = 0;
    //省略其他代码
    }
    

    背景:byte数组内存储的实际字节大小为146。

    那么根据上面第一节的描述,KeyValue对象占用,情况为:

    对象头:8(Mark Word)+4(指向类的指针,启用了压缩,所以指针占4字节,下同)=12
    byte[] 数组对象头:8(Mark Word)+4(指向类的指针) + 4(数组长度,占4字节)=16
    keyvalue大小 = 12(KeyValue对象头) + 4(bytes属性对byte[]数组引用) + 4(int类型 offset) + 4(int类型 length ) + 8(long类型 seqId )=32
    byte数组字节实际长度:146+16=162. byte数组是一个独立的对象,所以需要对齐填充。162需要对齐填充,填充结果为 168
    total_size_sum =
    keyvalue大小 + bytes数组大小 = 32 + 168(byte[] 数组对象实际占用存储空间) = 200

    edit heap size = 240 是统计的WALEdit ,源码在下面。cells 是一个ArrayList,所以在计算的时候,除了上面的200字节,还要加上ArrayList占用的空间。计算方式跟上面一样。

    public class WALEdit implements HeapSize {
    	  private ArrayList<Cell> cells = null; // KeyValue是Cell的实现类
    }
    

    由于不同的JVM实现,或者不同的机器,不同的启动参数,都可能造成实际占用空间不同,所以需要再实际运行过程中统计真实的占用情况,而不是简单的使用上面的公式计算。

    在hbase中有专门统计对象大小的工具类ClassSize:

    REFERENCE = memoryLayout.oopSize();
    
        OBJECT = memoryLayout.headerSize();
    
        ARRAY = memoryLayout.arrayHeaderSize();
    
        ARRAYLIST = align(OBJECT + REFERENCE + (2 * Bytes.SIZEOF_INT)) + align(ARRAY);
    
    //headerSize源码:
    private static class UnsafeLayout extends MemoryLayout {
        @SuppressWarnings("unused")
        private static final class HeaderSize {
          private byte a;
        }
    
        public UnsafeLayout() {
        }
    
        @Override
        int headerSize() {
          try {//这里使用Unsafe本地方法,来获取对象中第一个元素的偏移量。
            return (int) UnsafeAccess.theUnsafe.objectFieldOffset(
              HeaderSize.class.getDeclaredField("a"));
          } catch (NoSuchFieldException | SecurityException e) {
            LOG.error(e.toString(), e);
          }
          return super.headerSize();
        }
        //省略其他代码
    }
    

    ObjectFieldOffSet

    JAVA中对象的字段的定位可能通过staticFieldOffset方法实现,该方法返回给定field的内存地址偏移量,这个值对于给定的filed是唯一的且是固定不变的。

    第一个属性之前的空间也就是对象头占用的空间。以此来判断对象的大小情况更加准确一些。
    其他的也是采用类似运行时动态获取占用空间的方式,具体可以阅读hbase源码查看。

    end.

    展开全文
  • 一、通过Instrumentation获取内存 在java工程中添加如下代理类: package com.nineya.memorymeasurs; import java.lang.instrument.Instrumentation; public class MemoryMeasurs { static Instrumentation ...

    本文环境

    1. win 10
    2. jdk 1.8.0_241
    3. IntelliJ 2019.1.3

    一、通过Instrumentation获取内存

    1. 在java工程中添加如下代理类:
    package com.nineya.memorymeasurs;
    import java.lang.instrument.Instrumentation;
    
    public class MemoryMeasurs {
    
        static Instrumentation inst;
    
        // 由jvm注入
        public static void premain(String agentArgs, Instrumentation inst) {
            MemoryMeasurs.inst = inst;
        }
    
        // 取得对象大小
        public static long sizeOf(Object o) {
            if(inst == null) {
                throw new IllegalStateException("请在java的“-javaagent”命令行参数中运行。");
            }
            return inst.getObjectSize(o);
        }
    }
    

    上面的代理类能够实现基础的测量类对象内存占用的功能,在网上找到的更完整的版本如下,能够递归测量类对象引用的对象的占用的内存。

    package com.nineya.memorymeasurs;
    
    import java.lang.instrument.Instrumentation;
    import java.lang.reflect.Array;
    import java.lang.reflect.Field;
    import java.lang.reflect.Modifier;
    import java.util.IdentityHashMap;
    import java.util.Map;
    import java.util.Stack;
    /**
     * @author linsongwang
     * @date 2020/4/27
     */
    
    public class MemoryMeasurs {
        static Instrumentation inst;
    
        // 由jvm注入
        public static void premain(String agentArgs, Instrumentation instP) {
            inst = instP;
        }
    
        // 计算对象内存占用
        public static long sizeOf(Object o) {
            if(inst == null) {
                throw new IllegalStateException("请在java的“-javaagent”命令行参数中运行。");
            }
            return inst.getObjectSize(o);
        }
        /**
         * 递归计算当前对象占用空间总大小,包括当前类和超类的实例字段大小以及实例字段引用对象大小
         */
        public static long fullSizeOf(Object obj) {//深入检索对象,并计算大小
            Map<Object, Object> visited = new IdentityHashMap<Object, Object>();
            Stack<Object> stack = new Stack<Object>();
            long result = internalSizeOf(obj, stack, visited);
            while (!stack.isEmpty()) {//通过栈进行遍历
                result += internalSizeOf(stack.pop(), stack, visited);
            }
            visited.clear();
            return result;
        }
    
        //判定哪些是需要跳过的
        private static boolean skipObject(Object obj, Map<Object, Object> visited) {
            if (obj instanceof String) {
                if (obj == ((String) obj).intern()) {
                    return true;
                }
            }
            return (obj == null) || visited.containsKey(obj);
        }
    
        private static long internalSizeOf(Object obj, Stack<Object> stack, Map<Object, Object> visited) {
            if (skipObject(obj, visited)) {//跳过常量池对象、跳过已经访问过的对象
                return 0;
            }
            visited.put(obj, null);//将当前对象放入栈中
            long result = 0;
            result += sizeOf(obj);
            Class <?>clazz = obj.getClass();
            if (clazz.isArray()) {//如果数组
                if(clazz.getName().length() != 2) {// skip primitive type array
                    int length =  Array.getLength(obj);
                    for (int i = 0; i < length; i++) {
                        stack.add(Array.get(obj, i));
                    }
                }
                return result;
            }
            return getNodeSize(clazz , result , obj , stack);
        }
        //这个方法获取非数组对象自身的大小,并且可以向父类进行向上搜索
        private static long getNodeSize(Class <?>clazz , long result , Object obj , Stack<Object> stack) {
            while (clazz != null) {
                Field[] fields = clazz.getDeclaredFields();
                for (Field field : fields) {
                    if (!Modifier.isStatic(field.getModifiers())) {//这里抛开静态属性
                        if (field.getType().isPrimitive()) {//这里抛开基本关键字(因为基本关键字在调用java默认提供的方法就已经计算过了)
                            continue;
                        }else {
                            field.setAccessible(true);
                            try {
                                Object objectToAdd = field.get(obj);
                                if (objectToAdd != null) {
                                    stack.add(objectToAdd);//将对象放入栈中,一遍弹出后继续检索
                                }
                            } catch (IllegalAccessException ex) {
                                assert false;
                            }
                        }
                    }
                }
                clazz = clazz.getSuperclass();//找父类class,直到没有父类
            }
            return result;
        }
    }
    
    1. 修改META-INF\MANIFEST.MF文件,添加如下行,引用上面的代理类
    Premain-Class: com.nineya.memorymeasurs.MemoryMeasurs
    
    1. 在其他地方可以自由使用这个MemoryMeasurs代理类了。

    2. 编译工程为jar包,使用如下命令执行:

    java -javaagent:XXX.jar main方法所在的类
    
    // 示例
    java -javaagent:ObjectSize.jar  ObjectSizeTest
    

    二、通过jol包

    1.maven导包

            <dependency>
                <groupId>org.openjdk.jol</groupId>
                <artifactId>jol-core</artifactId>
                <version>0.9</version>
            </dependency>
    

    2.使用api

    import org.openjdk.jol.info.ClassLayout;
    
    // 取得map占用的空间
    Map<String, String> map = new HashMap<>();
    ClassLayout.parseInstance(map).instanceSize();
    

    3.jol只是获取对象占用的内存空间,不会递归获取对象引用的其他对象占用的内存空间,稍微修改上面的MemoryMeasurs类进行封装。

    package com.cl.graph.util;
    
    import org.openjdk.jol.info.ClassLayout;
    
    import java.lang.reflect.Array;
    import java.lang.reflect.Field;
    import java.lang.reflect.Modifier;
    import java.util.IdentityHashMap;
    import java.util.Map;
    import java.util.Stack;
    
    /**
     * @author linsongwang
     * @date 2020/4/27
     */
    
    public class ObjectShallowSize {
    
        // 计算对象内存占用
        public static long sizeOf(Object o) {
            return ClassLayout.parseInstance(o).instanceSize();
        }
    
        /**
         * 深入检索对象,递归计算当前对象占用空间总大小,包括当前类和父类类的实例字段大小以及实例字段引用对象大小
         */
        public static long fullSizeOf(Object obj) {//深入检索对象,并计算大小
            Map<Object, Object> visited = new IdentityHashMap<Object, Object>();
            Stack<Object> stack = new Stack<Object>();
            long result = internalSizeOf(obj, stack, visited);
            while (!stack.isEmpty()) {//通过栈进行遍历
                result += internalSizeOf(stack.pop(), stack, visited);
            }
            visited.clear();
            return result;
        }
    
        //判定哪些是需要跳过的
        private static boolean skipObject(Object obj, Map<Object, Object> visited) {
            if (obj instanceof String) {
                if (obj == ((String) obj).intern()) {
                    return true;
                }
            }
            return (obj == null) || visited.containsKey(obj);
        }
    
        private static long internalSizeOf(Object obj, Stack<Object> stack, Map<Object, Object> visited) {
            if (skipObject(obj, visited)) {//跳过常量池对象、跳过已经访问过的对象
                return 0;
            }
            visited.put(obj, null);//将当前对象放入栈中
            long result = 0;
            result += sizeOf(obj);
            Class<?> clazz = obj.getClass();
            if (clazz.isArray()) {//如果数组
                if (clazz.getName().length() != 2) {// skip primitive type array
                    int length = Array.getLength(obj);
                    for (int i = 0; i < length; i++) {
                        stack.add(Array.get(obj, i));
                    }
                }
                return result;
            }
            return getNodeSize(clazz, result, obj, stack);
        }
    
        //这个方法获取非数组对象自身的大小,并且可以向父类进行向上搜索
        private static long getNodeSize(Class<?> clazz, long result, Object obj, Stack<Object> stack) {
            while (clazz != null) {
                Field[] fields = clazz.getDeclaredFields();
                for (Field field : fields) {
                    if (!Modifier.isStatic(field.getModifiers())) {//这里抛开静态属性
                        if (field.getType().isPrimitive()) {//这里抛开基本关键字(因为基本关键字在调用java默认提供的方法就已经计算过了)
                            continue;
                        } else {
                            field.setAccessible(true);
                            try {
                                Object objectToAdd = field.get(obj);
                                if (objectToAdd != null) {
                                    stack.add(objectToAdd);//将对象放入栈中,一遍弹出后继续检索
                                }
                            } catch (IllegalAccessException ex) {
                                assert false;
                            }
                        }
                    }
                }
                clazz = clazz.getSuperclass();//找父类class,直到没有父类
            }
            return result;
        }
    
        public static long getGraphMemory(String graphName){
            Graph graph = GraphManage.getGraph(graphName);
            if (graph==null){
                System.out.println("图 "+graphName+" 不存在!");
                return 0;
            }
            System.out.println("递归获取内存中,该过程将非常长!");
            return fullSizeOf(graph);
        }
    }
    

    4.使用ObjectShallowSize获取对象内存占用

    Map<String, String> map = new HashMap<>();
    // 取得map占用的空间
    ObjectShallowSize.sizeOf(map);
    // 递归取得map占用的空间
    ObjectShallowSize.fullSizeOf(map);
    

    三、通过计算jvm内存空间取得

    // gc操作
    System.gc();
    // startMemory=totalMemory(总内存)-freeMemory(剩余内存)
    long startMemory = Runtime.getRuntime().totalMemory()-Runtime.getRuntime().freeMemory();
    
    // 在这里new需要测试内存占用的对象
    ...
    
    // gc操作
    System.gc();
    // endMemory=totalMemory(总内存)-freeMemory(剩余内存)
    long endMemory = Runtime.getRuntime().totalMemory()-Runtime.getRuntime().freeMemory();
    
    Log.info("内存占用:"+ (endMemory-startMemory));
    
    展开全文
  • 统计缓存大小(查看java对象所占的内存大小).
  • java中查看对象使用内存大小

    千次阅读 2019-08-06 22:19:33
    首先设定内存最大和最小一样: ...//查看jvm空闲内存大小,单位字节 long start = Runtime.getRuntime().freeMemory(); Map<String,String> map = new HashMap<>(); for(int i = 0 ;i < 4...

    首先设定内存最大和最小一样:

    在这里插入图片描述

    public static void main(String[] args){
            //查看jvm空闲内存大小,单位字节
           long start = Runtime.getRuntime().freeMemory();
          Map<String,String> map = new HashMap<>();
          for(int i = 0 ;i < 4000; i ++){
              map.put("11111"+i,"你叫什么名字");
          }
          //查看jvm空闲内存大小
          long end = Runtime.getRuntime().freeMemory();
          //获取map使用的内存大小,并将其转为兆单位
          double useMemory = (start - end)/1024.00/1024.00;
          //打印map使用的内存大小
          System.out.println("使用掉的内存:"+ useMemory + "M");
          //打印总内存大小
          System.out.println("内存总量:"+Runtime.getRuntime().totalMemory()/1024/1024 + "M");
          //保持map的引用
          for(Map.Entry<String, String> map1 : map.entrySet()){
              System.out.println(map1.getKey() + " :" + map1.getValue());
          }
        }
    

    在这里插入图片描述

    展开全文
  • 这里要介绍的是lucene提供的专门用于计算堆内存占用大小的工具类:RamUsageEstimator maven坐标 <dependency> <groupId>org.apache.lucene</groupId> <artifactId>lucene-core</...

    这里要介绍的是lucene提供的专门用于计算堆内存占用大小的工具类:RamUsageEstimator

    maven坐标

    <dependency>
          <groupId>org.apache.lucene</groupId>
          <artifactId>lucene-core</artifactId>
          <version>4.0.0</version>
    </dependency>
    

    常用方法如下:

    //计算指定对象及其引用树上的所有对象的综合大小,单位字节
    long RamUsageEstimator.sizeOf(Object obj)
    
    //计算指定对象本身在堆空间的大小,单位字节
    long RamUsageEstimator.shallowSizeOf(Object obj)
    
    //计算指定对象及其引用树上的所有对象的综合大小,返回可读的结果,如:2KB
    
    String RamUsageEstimator.humanSizeOf(Object obj)
    
    展开全文
  • 如何计算Java对象所占内存大小

    万次阅读 多人点赞 2018-05-24 11:42:12
    摘要:本文以如何计算Java对象占用内存大小为切入点,讨论计算Java对象占用堆内存大小的方法的基础上,详细讨论了Java对象头格式并结合JDK源码对对象头中的协议字段做了介绍,涉及内存模型、锁原理、分代GC、OOP-...
  • Java获取对象内存使用大小

    千次阅读 2019-01-11 16:58:15
    对于对象创建后内存使用情况,看了很多大佬的博客,由于自己对大佬写的流程(获取JAVA对象内存大小的方法)不太理解,经过多次的实验和尝试,最后我gitHub找到了类似上面的那个方法,下面直接贴上链接(这个是国外...
  • java获取对象所占用的内存大小

    千次阅读 2016-11-10 11:01:10
    java中快速获取某个对象所占用的内存大小: 用lucene核心包中的静态方法: org.apache.lucene.util.RamUsageEstimator.sizeof(Object object); api 链接地址:...
  • 测量Java对象所占内存大小

    万次阅读 2017-12-17 00:40:22
    背景: 相信大部分人都不会关注这个问题吧,只有一些偏执狂才会抓着这些不放,我们平时写代码时经常会new ArrayList(),new String()之类的,那么这些刚new出来的对象在内存中占用多大空间呢?随着作者一起去看看吧...
  • 查看java对象占用内存大小

    千次阅读 2019-10-31 21:39:55
    引入maven依赖: < dependency > < ...的方法输出对象占用大小信息: ...因为jvm要求对象所占的内存空间大小是8字节的整数倍,这个对象本来占17字节,为了对齐,补上了7字节,一共占24字节(8字节*3)。
  •  介绍两种获取JAVA对象内存大小的方法。 第一种:Instrumentation 简介: 使用java.lang.instrument 的Instrumentation来获取一个对象的内存大小。利用Instrumentation并且通过代理我们可以监测JVM运行的程序的...
  •    到目前为止,还没有做明确的优化工作。只是做了初始化选择工作,比如说:JVM部署模型...这一步将介绍如何评估应用需要的内存大小以及Java堆大小。首先需要判断出应用存活的数据的大小,存活数据的大小是决定配...
  • 然后,我们就可以main函数中尝试获取对象占用的内存大小了: public class C { private int x; private int y; public static void main(String [] args) { System.out.println(ObjectSizeFetcher.get...
  • 如何查看Java对象占用JVM内存大小

    千次阅读 2018-01-09 17:17:22
    之前遇到要查看缓存大小,找了很多方法都不是很合适,从同事那里得知一个很好、很准确的方法。现分享如下: private ListMapString,Object>> paramList=new ArrayListMapString,Object>>(); paramList=sqlMap....
  • Java计算一个对象占用内存大小

    千次阅读 2015-05-27 17:13:02
    Java计算一个对象占用内存大小
  • java如何获取一个对象大小

    千次阅读 2019-09-25 13:21:51
    但当一个系统的内存有限,或者某块程序代码允许使用的内存大小有限制,又或者设计一个缓存机制,当存储对象内存超过固定值之后写入磁盘做持久化等等,总之我们希望像写C一样,java也能有方法实现获取对象占用内存的...
  • 转载:... 一步步优化JVM 目录 一:JVM概述、方法及需求 二:JVM部署模型和JVM Runtime 三:GC优化基础 四:决定Java堆大小以及内存占用 五:优化延迟或者响应时...
  • java对象在内存中的分配

    万次阅读 多人点赞 2017-02-10 22:45:33
    堆内存中存放的是new出的对象,new出的对象只包含成员变量。  栈内存中:存放的是局部成员变量。对于基本的数据类型存放的是基本变量的值,而对于对象变量,存放的是堆内存的地址。  静态、常量区:存放的是静态...
  • Java对象占用内存大小

    千次阅读 2014-03-16 07:40:38
    Java对象占用内存大小   转 new Object()将占用多少bytes的内存空间?  原生类型(primitive type)的内存占用 Primitive Type Memory Required(bytes) ————————————————————— ...
  • 我的Java EE企业经验中,由于Java堆容量和调整不足,我遇到了多个性能问题案例。 本文将为您提供5个技巧,这些技巧可以帮助您确定当前或新生产环境的最佳Java堆大小。 这些技巧中的一些对于预防和解决java.lang....
  • 目录 一、JAVA内存结构 1.1 JVM启动流程: 1.2 JVM基本结构 1.2.1基本结构图 1.2.2 Java中的内存分配 ...二、Java内存模型 ...2.1 主内存和工作内存 ...2.2 内存间交互操作 ...三、Java对象模型 3.1 oop-klass...
  • Java 内存管理

    2019-05-13 11:32:48
    目录 1.什么是内存? 2.内存有什么优势? 3.内存的使用 3.1内存的设置 ...3.2内存的创建 ...3.3内存的回收 ...Java中分配的非空对象都是由Java虚拟机的垃圾收集器管理的,都是...
  • 如何查看java对象所占的内存大小

    万次阅读 2013-06-21 13:17:25
    参考:... ... 我们为什么想要知道对象所占对内存大小呢? (1)做一些cache的时候,我们不可能把数据库的所有的数据都缓存到内存里面,我们要估计缓
  • java堆内存和栈内存的区别

    千次阅读 2015-11-03 14:05:48
    一段时间之前,我写了两篇文章文章分别是Java的垃圾回收和Java的值传递,从那之后我收到了很多要求解释Java内存和栈内存的邮件,并且要求...不论什么时候我们创建了对象,它将一直会在堆内存上创建。垃圾回收运行...
  • 4种方式配置不同作用域的jvm的堆栈内存! 1、Eclise 中设置jvm内存: 修改eclipse的配置文件,对所有工程都起作用  修改eclipse根目录下的eclipse.ini文件  -vmargs //虚拟机设置  -Xms40m //初始内存  -Xmx...
  • java如何获取对象在内存中的大小

    千次阅读 2007-03-19 15:47:00
    public class T { public static void main(String[] args) throws Exception { // 创建 1000 个 String String strA[] = new ...System.out.println("一个String对象内存:" (start - end)/1000.0); } } 
  • 最近学习java对象内存布局方面的一些知识,主要是想知道一个java对象到底占用多少内存空间,以及java对象内存中到底是什么样子的。c/c++中的sizeof运算符能够方便地告诉我们一个变量占用的内存空间,但是在java...

空空如也

空空如也

1 2 3 4 5 ... 20
收藏数 241,316
精华内容 96,526
关键字:

java获取对象在堆内存的大小

java 订阅