Java 基本数据类型 sizeof 功能【转】

简介:

转自:http://blog.csdn.net/sunboy_2050/article/details/7310008

Java基本数据类型
int     32bit
short   16bit
long    64bit
byte    8bit
char    16bit
float   32bit
double  64bit
boolean 1bit,This data type represents one bit of information, but its "size" isn't something that's precisely defined.( ref
 
Java基本数据类型大小
[java]  view plain  copy
 
 print?
  1.     private static void calSize() {  
  2.         System.out.println("Integer: " + Integer.SIZE/8);           // 4  
  3.         System.out.println("Short: " + Short.SIZE/8);               // 2      
  4.         System.out.println("Long: " + Long.SIZE/8);                 // 8  
  5.         System.out.println("Byte: " + Byte.SIZE/8);                 // 1  
  6.         System.out.println("Character: " + Character.SIZE/8);       // 2  
  7.         System.out.println("Float: " + Float.SIZE/8);               // 4  
  8.         System.out.println("Double: " + Double.SIZE/8);             // 8  
  9. //      System.out.println("Boolean: " + Boolean);  
  10.     }  
 
Java中模拟c中对sizeof的实现
思路:利用java中GC内存回收前后的heap size差别,得出每个object的大小

 


这是一个程序,java中没有现成的sizeof的实现,原因主要是java中的基本数据类型的大小都是固定的,所以看上去没有必要用sizeof这个关键字。
实现的想法是这样的:java.lang.Runtime类中有一些简单的能涉及到内存管理的函数:
Every Java application has a single instance of class Runtime that allows the application to interface with the environment in which the application is running. The current runtime can be obtained from the getRuntime method.
 long
freeMemory()
Returns the amount of free memory in the Java Virtual Machine.
 void
gc()
Runs the garbage collector.
static  Runtime
getRuntime()
Returns the runtime object associated with the current Java application.
 long
maxMemory()
Returns the maximum amount of memory that the Java virtual machine will attempt to use.
 void
runFinalization()
Runs the finalization methods of any objects pending finalization.
使用这些简单的内存访问,可以得到内存的一些情况,我们通过建立一个大的某个类的数组,来查看内存用了多少,进而可以求得类的大小。
 
源码:

 

[java]  view plain  copy
 
 print?
  1.     private static void calSize2() {  
  2.         runGC();  
  3.   
  4.         long heap1 = 0;  
  5.         final int count = 100000;  
  6.         Object[] objs = new Object[count];  
  7.   
  8.         for(int i=-1; i<count; i++) {  
  9.             Object obj = null;  
  10.             obj = new Object();                 // 8  
  11. //          obj = new Integer( i );             // 16  
  12. //          obj = new Short( (short)i );        // 16  
  13. //          obj = new Long( i );                // 16  
  14. //          obj = new Byte( (byte)0 );          // 16  
  15. //          obj = new Character( (char)i );     // 16  
  16. //          obj = new Float( i );               // 16  
  17. //          obj = new Double( i );              // 16  
  18. //          obj = new Boolean( true );          // 16  
  19. //          obj = new String();                 // 40  
  20.               
  21.               
  22.             if(i<0){  
  23.                 obj = null;  
  24.                 runGC();  
  25.                 heap1 = usedMemory();   // before memory size  
  26.             } else {  
  27.                 objs[i] = obj;   
  28.             }  
  29.         }  
  30.   
  31.         runGC();  
  32.         long heap2 = usedMemory();      // after memory size  
  33.           
  34.         final int size = (int)Math.round( (heap2 - heap1)/(double)count );  
  35.         System.out.println("heap1 = " + heap1 + "; heap2 = " + heap2);  
  36.         System.out.println("heap2-heap1 = " + (heap2 - heap1) + "; " + objs[0].getClass().getSimpleName() + " size = " + size);  
  37.           
  38.         for(int i=0; i<count; i++) {  
  39.             objs[i] = null;  
  40.         }  
  41.         objs = null;  
  42.         runGC();  
  43.     }  
  44.       
  45.     private static void runGC() {  
  46.         for(int i=0; i<4; i++) {  
  47.             long usedMem1 = usedMemory();  
  48.             long usedMem2 = Long.MAX_VALUE;  
  49.               
  50.             for(int j=0; (usedMem1<usedMem2) && (j<500); j++) {  
  51.                 rTime.runFinalization();  
  52.                 rTime.gc();  
  53.                 Thread.yield();  
  54.                   
  55.                 usedMem2 = usedMem1;  
  56.                 usedMem1 = usedMemory();  
  57.             }  
  58.         }  
  59.     }  
  60.       
  61.     private static long usedMemory() {  
  62.         return rTime.totalMemory() - rTime.freeMemory();  
  63.     }  

 

 
注意:Object[] objects = new Object[count];
只是分配了数组空间,没有分配对象的空间。数组中只有引用而已。
 
结论:下代码测试基本对象时,得出的结果象下面:   
Object obj = null;
obj = new Object(); // 8
obj = new Integer( i ); // 16
obj = new Short( (short)i ); // 16
obj = new Long( i ); // 16
obj = new Byte( (byte)0 ); // 16
obj = new Character( (char)i ); // 16
obj = new Float( i ); // 16
obj = new Double( i ); // 16
obj = new Boolean( true ); // 16
obj = new String(); // 40
怎么会这样呢???解释如下:
 
这个例子写的很好,正好说明了java中基本类型封装对象所占内存的大小.   
1.简单的Object对象要占用8个字节的内存空间,因为每个实例都至少必须包含一些最基本操作,比如:wait()/notify(),equals(),   hashCode()等   
2.使用Integer对象占用了16个字节,而int占用4个字节,说了封装了之后内存消耗大了4倍   

3.那么Long看起来比Integer对象应该使用更多空间,结果Long所占的空间也是16个字节.   
那么就正好说明了JVM的对于基本类型封装对象的内存分配的规则是如下:   
Object所占内存(8个字节)+最大基本类型(long)所占内存(8个字节)   =   16字节.   
JVM强制使用8个字节作为边界.   
所以所有基本类型封装对象所占内存的大小都是16字节.
但是还是有区别,比如:
Integer对象虽然占用了16个字节的内存,但是只是利用了 Object所占内存(8个字节)+int所占内存(4个字节)   =   12字节.
还有4个字节根本没有被使用.呵呵,仔细分析了一晚,还是有很多收获的
 
 
 
 
参考推荐:
Primitive Data Types (SUN 官方文档)











本文转自张昺华-sky博客园博客,原文链接:http://www.cnblogs.com/sky-heaven/p/5882318.html,如需转载请自行联系原作者

相关文章
|
8天前
|
存储 缓存 安全
Java中的数据类型
Java语言提供了八种基本类型,分为4类8种:六个数值型(四个整数型byte、short、int、long,两个浮点型float、double)、一个字符型char和一个布尔型boolean。每种基本类型有固定的位数、取值范围及默认值。此外,还存在`void`类型,但无法直接操作。基本类型支持隐式和显式类型转换,并有对应的包装类如`Integer`、`Double`等,用于在需要对象的场景中使用。包装类支持自动装箱与拆箱机制,简化了基本类型与引用类型的转换,但需要注意性能和空指针异常等问题。
Java中的数据类型
|
20天前
|
Java
java实现从HDFS上下载文件及文件夹的功能,以流形式输出,便于用户自定义保存任何路径下
java实现从HDFS上下载文件及文件夹的功能,以流形式输出,便于用户自定义保存任何路径下
81 34
|
1月前
|
安全 Java 测试技术
🎉Java零基础:全面解析枚举的强大功能
【10月更文挑战第19天】本文收录于「滚雪球学Java」专栏,专业攻坚指数级提升,希望能够助你一臂之力,帮你早日登顶实现财富自由🚀;同时,欢迎大家关注&&收藏&&订阅!持续更新中,up!up!up!!
121 60
|
1月前
|
Java
Java基础之数据类型
Java基础之数据类型
20 6
|
1月前
|
Java
在Java中如何将基本数据类型转换为String
在Java中,可使用多种方法将基本数据类型(如int、char等)转换为String:1. 使用String.valueOf()方法;2. 利用+运算符与空字符串连接;3. 对于数字类型,也可使用Integer.toString()等特定类型的方法。这些方法简单高效,适用于不同场景。
60 7
|
1月前
|
Java
Java 8 引入的 Streams 功能强大,提供了一种简洁高效的处理数据集合的方式
Java 8 引入的 Streams 功能强大,提供了一种简洁高效的处理数据集合的方式。本文介绍了 Streams 的基本概念和使用方法,包括创建 Streams、中间操作和终端操作,并通过多个案例详细解析了过滤、映射、归并、排序、分组和并行处理等操作,帮助读者更好地理解和掌握这一重要特性。
35 2
|
1月前
|
存储 缓存 Java
大厂面试必看!Java基本数据类型和包装类的那些坑
本文介绍了Java中的基本数据类型和包装类,包括整数类型、浮点数类型、字符类型和布尔类型。详细讲解了每种类型的特性和应用场景,并探讨了包装类的引入原因、装箱与拆箱机制以及缓存机制。最后总结了面试中常见的相关考点,帮助读者更好地理解和应对面试中的问题。
73 4
|
1月前
|
存储 消息中间件 NoSQL
使用Java操作Redis数据类型的详解指南
通过使用Jedis库,可以在Java中方便地操作Redis的各种数据类型。本文详细介绍了字符串、哈希、列表、集合和有序集合的基本操作及其对应的Java实现。这些示例展示了如何使用Java与Redis进行交互,为开发高效的Redis客户端应用程序提供了基础。希望本文的指南能帮助您更好地理解和使用Redis,提升应用程序的性能和可靠性。
42 1
|
2月前
|
存储 Java 关系型数据库
[Java]“不同族”基本数据类型间只能“强转”吗?
本文探讨了不同位二进制表示范围的计算方法,重点分析了Java中int和char类型之间的转换规则,以及float与int类型之间的转换特性。通过具体示例说明了显式和隐式转换的条件和限制。
40 0
[Java]“不同族”基本数据类型间只能“强转”吗?
|
2月前
|
Java
java实现从HDFS上下载文件及文件夹的功能,以流形式输出,便于用户自定义保存任何路径下
java实现从HDFS上下载文件及文件夹的功能,以流形式输出,便于用户自定义保存任何路径下
69 2
java实现从HDFS上下载文件及文件夹的功能,以流形式输出,便于用户自定义保存任何路径下