java对象占用内存分析

来源:互联网 发布:要怎么样才能精通java 编辑:程序博客网 时间:2024/04/28 01:49

前言

空对象占8个字节 

数据成员的话,你把数据成员按基本数据类型和对象引用分开统计。 
基本数据类型按byte/boolean=1,char/short=2,int/float=4,long/double=8,累加,然后对齐到8的倍数。 

对象引用按每个4字节,累加,然后对齐到8个字节的倍数。 


对象占用字节数=基本的8字节+基本数据类型所占的+对象引用所占的 

比如 
class A{ 
int a; 
char b; 

占 8(基本)+8(int 4+char 2=6,对齐到8)= 16个字节 
再比如: 
class B{ 
Integer a; 
long b; 
byte c; 

占 8(基本)+8(long8+byte1=9,对齐到8)+8(对象引用4,对齐到8)=32个字节 

=============== 
如果你是从别的类继承的,父类的也要算上。 


直接上代码

实现类

  1. public abstract class SizeOf {     
  2.     
  3.     private final Runtime s_runtime = Runtime.getRuntime();     
  4.     
  5.     /**   
  6.      *   
  7.      * 子类负责覆盖该方法以提供被测试类的实例   
  8.      *   
  9.      * @return 被测试类的实例   
  10.      */    
  11.     protected abstract Object newInstance();     
  12.     
  13.     /**   
  14.      *   
  15.      * 计算实例的大小(字节数)   
  16.      *   
  17.      * @return 实例所占内存的字节数   
  18.      * @throws Exception   
  19.      */    
  20.     public int size() throws Exception {     
  21.     
  22.         // 垃圾回收     
  23.         runGC();     
  24.     
  25.         // 提供尽可能多(10万)的实例以使计算结果更精确     
  26.         final int count = 100000;     
  27.         Object[] objects = new Object[count];     
  28.     
  29.         // 实例化前堆已使用大小     
  30.         long heap1 = usedMemory();     
  31.         // 多实例化一个对象     
  32.         for (int i = -1; i < count; ++i) {     
  33.             Object object = null;     
  34.     
  35.             // 实例化对象     
  36.             object = newInstance();     
  37.     
  38.             if (i >= 0) {     
  39.                 objects[i] = object;     
  40.             } else {     
  41.                 // 释放第一个对象     
  42.                 object = null;     
  43.                 // 垃圾收集     
  44.                 runGC();     
  45.                 // 实例化之前堆已使用大小     
  46.                 heap1 = usedMemory();     
  47.             }     
  48.         }     
  49.     
  50.         runGC();     
  51.         // 实例化之后堆已使用大小     
  52.         long heap2 = usedMemory();     
  53.         final int size = Math.round(((float) (heap2 - heap1)) / count);     
  54.     
  55.         // 释放内存     
  56.         for (int i = 0; i < count; ++i) {     
  57.             objects[i] = null;     
  58.         }     
  59.         objects = null;     
  60.         return size;     
  61.     }     
  62.     
  63.     private void runGC() throws Exception {     
  64.         // 执行多次以使内存收集更有效     
  65.         for (int r = 0; r < 4; ++r) {     
  66.             _runGC();     
  67.         }     
  68.     }     
  69.     
  70.     private void _runGC() throws Exception {     
  71.         long usedMem1 = usedMemory();     
  72.         long usedMem2 = Long.MAX_VALUE;     
  73.         for (int i = 0; (usedMem1 < usedMem2) && (i < 500); ++i) {     
  74.             s_runtime.runFinalization();     
  75.             s_runtime.gc();     
  76.             Thread.currentThread().yield();     
  77.             usedMem2 = usedMem1;     
  78.             usedMem1 = usedMemory();     
  79.         }     
  80.     }     
  81.     
  82.     /**   
  83.      *   
  84.      * 堆中已使用内存   
  85.      *   
  86.      * @return 堆中已使用内存   
  87.      */    
  88.     private long usedMemory() {     
  89.         return s_runtime.totalMemory() - s_runtime.freeMemory();     
  90.     }     
  91. }    

测试

  1. public class SizeOfObject extends SizeOf {     
  2.     
  3.     @Override    
  4.     protected Object newInstance() {     
  5.         return new Object();     
  6.     }     
  7.     
  8.     public static void main(String[] args) throws Exception {     
  9.         SizeOf sizeOf = new SizeOfObject();     
  10.         System.out.println("所占内存:" + sizeOf.size() + "字节");     
  11.     }     
  12. }    
输出为:所占内存:8字节 


利用序列化(Serializable)计算对象的大小 
下面代码可以计算session的大小: 
将session中的所有对象输出到文件中,文件的大小就是对象的大小. 

  1. try {     
  2.     FileOutputStream f = new FileOutputStream("c:/sessionFiles");     
  3.     ObjectOutputStream s = new ObjectOutputStream(f);     
  4.     s.writeObject("session:");     
  5.     HttpSession session = request.getSession(false);     
  6.     Enumeration names = session.getAttributeNames();     
  7.     while(names.hasMoreElements()){     
  8.         s.writeObject(session.getAttribute((String) names.nextElement()));     
  9.     }     
  10.     s.flush();     
  11.     s.close();     
  12.     f.close();     
  13. catch (Exception e) {     
  14.     e.printStackTrace();     
  15. }    



0 0
原创粉丝点击