`

Java对象的大小

阅读更多

基本数据的类型的大小是固定的,这里就不多说了。对于非基本类型的Java对象,其大小就值得商榷。

在Java中,一个空Object对象的大小是8byte,这个大小只是保存堆中一个没有任何属性的对象的大小。看下面语句:

  Object ob = new Object();

 

这样在程序中完成了一个Java对象的生命,但是它所占的空间为:4byte+8byte。4byte是上面部分所说的Java栈中保存引用的 所需要的空间。而那8byte则是Java堆中对象的信息。因为所有的Java非基本类型的对象都需要默认继承Object对象,因此不论什么样的 Java对象,其大小都必须是大于8byte。

 

有了Object对象的大小,我们就可以计算其他对象的大小了。

Class NewObject { int count; boolean flag; Object ob; }

 

其大小为:空对象大小(8byte)+int大小(4byte)+Boolean大小(1byte)+空Object引用的大小 (4byte)=17byte。但是因为Java在对对象内存分配时都是以8的整数倍来分,因此大于17byte的最接近8的整数倍的是24,因此此对象 的大小为24byte。

 

这里需要注意一下基本类型的包装类型的大小。因为这种包装类型已经成为对象了,因此需要把他们作为对象来看待。包装类型的大小至少是 12byte(声明一个空Object至少需要的空间),而且12byte没有包含任何有效信息,同时,因为Java对象大小是8的整数倍,因此一个基本 类型包装类的大小至少是16byte。这个内存占用是很恐怖的,它是使用基本类型的N倍(N>2),有些类型的内存占用更是夸张(随便想下就知道 了)。因此,可能的话应尽量少使用包装类。在JDK5.0以后,因为加入了自动类型装换,因此,Java虚拟机会在存储方面进行相应的优化。

 

public class CacheSize { 
     /**
      * Returns the size in bytes of a basic Object. This method should only
      * be used for actual Object objects and not classes that extend Object.
      *
      * @return the size of an Object.
      */ 
     public static int sizeOfObject() { 
         return 4; 
     } 
     /**
      * Returns the size in bytes of a String.
      *
      * @param string the String to determine the size of.
      * @return the size of a String.
      */ 
     public static int sizeOfString(String string) { 
         if (string == null) { 
             return 0; 
         } 
         return 4 + string.length()*2; 
     } 
     /**
      * Returns the size in bytes of a primitive int.
      *
      * @return the size of a primitive int.
      */ 
     public static int sizeOfInt() { 
         return 4; 
     } 
     /**
      * Returns the size in bytes of a primitive char.
      *
      * @return the size of a primitive char.
      */ 
     public static int sizeOfChar() { 
         return 2; 
     } 
     /**
      * Returns the size in bytes of a primitive boolean.
      *
      * @return the size of a primitive boolean.
      */ 
     public static int sizeOfBoolean() { 
         return 1; 
     } 
     /**
      * Returns the size in bytes of a primitive long.
      *
      * @return the size of a primitive long.
      */ 
     public static int sizeOfLong() { 
         return 8; 
     } 
     /**
      * Returns the size in bytes of a primitive double.
      *
      * @return the size of a primitive double.
      */ 
     public static int sizeOfDouble() { 
         return 8; 
     } 
     /**
      * Returns the size in bytes of a Date.
      *
      * @return the size of a Date.
      */ 
     public static int sizeOfDate() { 
         return 12; 
     } 
     /**
      * Returns the size in bytes of a Properties object. All properties and
      * property names must be Strings.
      *
      * @param properties the Properties object to determine the size of.
      * @return the size of a Properties object.
      */ 
     public static int sizeOfProperties(Properties properties) { 
         if (properties == null) { 
             return 0; 
         } 
         //Base properties object 
         int size = 36; 
         //Add in size of each property 
         Enumeration enum = properties.elements(); 
         while(enum.hasMoreElements()) { 
             String prop = (String)enum.nextElement(); 
             size += sizeOfString(prop); 
         } 
         //Add in property names 
         enum = properties.propertyNames(); 
         while(enum.hasMoreElements()) { 
             String prop = (String)enum.nextElement(); 
             size += sizeOfString(prop); 
         } 
         return size; 
     } 
     /**
      * Returns the size in bytes of a Map object. All keys and
      * values <b>must be Strings</b>.
      *
      * @param map the Map object to determine the size of.
      * @return the size of the Map object.
      */ 
     public static int sizeOfMap(Map map) { 
         if (map == null) { 
             return 0; 
         } 
         //Base map object -- should be something around this size. 
         int size = 36; 
         //Add in size of each value 
         Iterator iter = map.values().iterator(); 
         while(iter.hasNext()) { 
             String value = (String)iter.next(); 
             size += sizeOfString(value); 
         } 
         //Add in each key 
         iter = map.keySet().iterator(); 
         while(iter.hasNext()) { 
             String key = (String)iter.next(); 
             size += sizeOfString(key); 
         } 
         return size; 
     } 
 }

分享到:
评论

相关推荐

    计算java对象大小

    总结来说,理解Java对象大小的计算对于优化内存使用、防止内存泄漏以及提高应用程序性能至关重要。开发人员需要了解不同方法的优缺点,并根据实际需求选择合适的方式。同时,应当注意,过于关注单个对象的大小可能...

    测量Java对象大小的demo

    本示例“测量Java对象大小的demo”提供了一种方法,通过使用Java的`java.lang.instrument`包来注入`javaagent`,进而利用`Instrumentation`接口测量Java对象的精确内存占用。下面我们将详细探讨这一过程。 首先,`...

    java 通过sizeOf计算一个对象的大小

    但是,Java API本身并不提供直接获取对象大小的方法。为了计算对象大小,我们需要借助一些第三方库或者自行实现。 一个常见的第三方库是`DeepSizeOf`,它来自Eclipse Collections框架,提供了类似于C++中的`sizeof`...

    【小知识】第4期 Java对象大小怎么算

    【小知识】第4期_Java对象大小怎么算

    [Java拾遗]Java对象大小探究

    NULL 博文链接:https://langyu.iteye.com/blog/1167581

    java 对象 内存 大小

    当我们谈论“Java对象内存大小”时,我们通常指的是一个Java对象在内存中占据的空间,包括对象头、实例字段以及可能的对齐填充。这个知识点对于开发高效缓存系统尤其重要,因为缓存需要精确管理内存来最大化存储效率...

    计算java对象的大小的方法

    本文将深入探讨如何计算Java对象的大小,以及这个知识点在实际开发中的应用。 首先,Java对象的大小不仅仅包括其字段的大小,还包括对象头(object header)的大小,对于HotSpot虚拟机,它包含了对齐填充、Mark ...

    java SizeOf 对象的大小

    NULL 博文链接:https://spice.iteye.com/blog/1104340

    JAVA对象所占内存大小计算例子

    本文将深入探讨如何计算Java对象所占内存,并通过提供的代码示例进行详细解析。 首先,我们需要理解Java对象内存占用的基本原理。每个Java对象都由三部分组成:对象头(Object Header)、实例数据(Instance Data)...

    计算一个Java对象占用字节数的方法

    本篇文章将深入探讨如何计算Java对象占用的内存字节数,以及影响这一数值的因素。 首先,Java对象在堆内存中由四个部分组成:对象头(A)、基本类型域(B)、引用类型域(C)和填充物(D)。 **对象头(A)**: ...

    统计缓存(java对象所占的内存)大小

    本文将深入探讨如何统计缓存(尤其是Java对象)所占的内存大小,以及这对理解程序内存消耗的重要性。 首先,我们要知道Java对象的内存开销主要由三部分组成:对象头、实例数据和对齐填充。对象头包含对象的类型信息...

    测试java对象占用内存大小的例子

    例如,`sun.misc.Unsafe`类(虽然非标准,但广泛使用)提供了访问内存的能力,包括获取对象大小。然而,需要注意的是,这个类在Java 9及以后的版本中被弃用,并且在某些JRE中可能不可用。 `SizeOfObject.java`可能...

    Java对象池实现源码

    本篇文章将深入探讨Java对象池的实现原理,以及如何借鉴"Jakarta Commons Pool"组件来设计一个轻量级的对象池。 一、对象池的基本概念 对象池的基本工作流程包括以下几个步骤: 1. 初始化:预创建一定数量的对象并...

    java-sizeof-0.0.4:一个查看java对象占用内存大小

    本文将深入探讨Java中的对象内存占用,以及如何使用"java-sizeof-0.0.4"工具来查看Java对象在内存中的大小。 在Java中,内存主要分为堆内存(Heap)和栈内存(Stack)。对象通常存储在堆内存中,而基本类型的变量和...

    java对象创建过程

    ### Java对象创建过程详解 在Java编程语言中,对象是程序的基本单元,一切皆对象这一概念使得Java在面向对象编程领域具有重要的地位。本文将详细阐述Java对象的创建过程,帮助读者深入理解Java基础。 #### 一、类...

    JAVA对象以及数据的工具类

    本篇文章将深入探讨Java中的对象、基础类型以及数据处理相关的工具类。 首先,让我们关注Java中的基础类型。Java有八种原始数据类型:byte、short、int、long、float、double、char和boolean。为了方便处理这些类型...

    Java对象内存布局 - 小分析

    本篇文章将深入探讨Java对象在JVM内存中的布局,帮助我们理解JVM是如何存储和管理对象的。 首先,我们要知道JVM内存主要分为以下几个区域: 1. **堆内存(Heap)**:这是Java对象的主要存储区域,所有通过`new`...

    Java 面向对象 练习题与答案

    Java 面向对象编程练习题与答案 本资源摘要信息涵盖了 Java 面向对象编程的多个知识点,包括 Font 类、Toolkit 类、包机制、抽象类、数组操作等。 1. Font 类: Font 类是 Java 中的一个类,用于设置程序中的字体...

    Java 对象(数组)占多大空间(几个字节) 手把手做实验

    总之,Java对象和数组的内存占用取决于JVM的配置、对象的字段、数组的元素类型和长度等因素。开启或关闭压缩选项会影响对象和数组引用的大小,进而影响整体的内存占用。对于内存优化和性能调优来说,了解这些细节至...

    java中的栈(深层了解java虚拟机对对象的内存分布)

    ### 深层解析Java虚拟机中的栈与堆:对象的内存分布 #### 核心概念:栈与堆的本质及作用 在Java编程语言中,理解栈(stack)和堆(heap)的概念及其工作原理对于深入掌握Java虚拟机(JVM)如何管理内存至关重要。栈和堆...

Global site tag (gtag.js) - Google Analytics