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,如需转载请自行联系原作者

相关文章
|
2月前
|
安全 Java API
Java中的Lambda表达式:简洁与功能的结合
Java中的Lambda表达式:简洁与功能的结合
354 211
|
11天前
|
安全 Java
使用Java多态性进行数据类型转换
以上示范了如何通过多态性来执行安全有效地对于Java对象间相互之间进行正确方式与场合下正确格式与条件限定内对于各个层级关系内部成员及其功能调取与应有操作处理过程,并通过 `instanceof`关键字确保了程序运行期间遵循逻辑合理并符合预设规则条件限定内正常工作流程而无需担忧潜藏风险问题出现可能带来影响结果质量问题情况存在可能。
50 12
|
2月前
|
JavaScript Java 微服务
现代化 Java Web 在线商城项目技术方案与实战开发流程及核心功能实现详解
本项目基于Spring Boot 3与Vue 3构建现代化在线商城系统,采用微服务架构,整合Spring Cloud、Redis、MySQL等技术,涵盖用户认证、商品管理、购物车功能,并支持Docker容器化部署与Kubernetes编排。提供完整CI/CD流程,助力高效开发与扩展。
327 63
|
23天前
|
存储 数据可视化 Java
Java Stream API 的强大功能
Java Stream API 是 Java 8 引入的重要特性,它改变了集合数据的处理方式。通过声明式语法,开发者可以更简洁地进行过滤、映射、聚合等操作。Stream API 支持惰性求值和并行处理,提升了代码效率和可读性,是现代 Java 开发不可或缺的工具。
Java Stream API 的强大功能
|
7月前
|
存储 Java
# 【Java全栈学习笔记-U1-day02】变量+数据类型+运算符
本篇笔记主要围绕Java全栈学习的第二天内容展开,涵盖了变量、数据类型、运算符以及Scanner类的应用。首先介绍了变量的概念与命名规范,以及如何定义和使用变量;接着详细讲解了Java中的基本数据类型,包括整型、浮点型、字符型、布尔型等,并通过实例演示了数据类型的运用。随后,深入探讨了各类运算符(赋值、算术、关系、逻辑)及其优先级,帮助理解表达式的构成。最后,介绍了如何利用Scanner类实现用户输入功能,并通过多个综合示例(如计算圆面积、购物打折、变量交换及银行利息计算)巩固所学知识。完成相关作业将进一步加深对这些基础概念的理解与实践能力。
102 13
|
2月前
|
前端开发 JavaScript Java
Java 项目实战城市公园信息管理系统开发流程与实用功能实现指南
本系统基于Java开发,采用Spring Boot后端框架与Vue.js前端框架,结合MySQL数据库,构建了一个高效的城市公园信息管理系统。系统包含管理员、用户和保洁人员三大模块,涵盖用户管理、园区信息查询、订票预约、服务管理等功能,提升公园管理效率与服务质量。
83 6
|
2月前
|
安全 Java 数据库
Java 项目实战病人挂号系统网站设计开发步骤及核心功能实现指南
本文介绍了基于Java的病人挂号系统网站的技术方案与应用实例,涵盖SSM与Spring Boot框架选型、数据库设计、功能模块划分及安全机制实现。系统支持患者在线注册、登录、挂号与预约,管理员可进行医院信息与排班管理。通过实际案例展示系统开发流程与核心代码实现,为Java Web医疗项目开发提供参考。
103 2
|
2月前
|
存储 缓存 算法
Java数据类型与运算符深度解析
本文深入解析Java中容易混淆的基础知识,包括八大基本数据类型(如int、Integer)、自动装箱与拆箱机制,以及运算符(如&与&&)的使用区别。通过代码示例剖析内存布局、取值范围及常见陷阱,帮助开发者写出更高效、健壮的代码,并附有面试高频问题解析,夯实基础。
|
2月前
|
机器学习/深度学习 算法 Java
Java 大视界 -- Java 大数据机器学习模型在生物信息学基因功能预测中的优化与应用(223)
本文探讨了Java大数据与机器学习模型在生物信息学中基因功能预测的优化与应用。通过高效的数据处理能力和智能算法,提升基因功能预测的准确性与效率,助力医学与农业发展。