使用计算总内存大小的方法确定jvm中为对象分配的存储空间大小

最近发现产品的java程序,占用内存变大很多。由于是从之前的32位server转到使用64位server,所以很有可能是不同架构下jvm分配内存大小不同导致的。

JAVA中没有类似C语言的sizeof函数,所以要确定jvm为基本类型或特定对象分配的内存大小,看起来比较困难。

下面的代码通过新建大量Object计算内存总大小的方式,来确定为每个对象分配的内存大小。

public class Sizeof
{
	public static void main (String [] args) throws Exception
	{
		testMem(1);
		testMem(2);
		testMem(3);
	}
    private static void testMem (int index) throws Exception
    {
        // Warm up all classes/methods we will use
        runGC ();
        usedMemory ();
        // Array to keep strong references to allocated objects
        final int count = 100000;
        Object [] objects = new Object [count];
        
        long heap1 = 0;
        // Allocate count+1 objects, discard the first one
		String testObj="";
		int x = 1;
		long y = 1;
		String z = "";
        for (int i = -1; i < count; ++ i)
        {
            Object object = null;
            
            // Instantiate your data here and assign it to object
            
            object = new Object ();
			switch (index) {			
				case 1: 					
					object = new Integer (x);
					testObj="Integer"; 
					break;					
				case 2: 					
					object = new Long (y);
					testObj="Long"; 
					break;			
				case 3: 					
					object = new String (z);
					testObj="String"; 
					break;
            }
			
            if (i >= 0)
                objects [i] = object;
            else
            {
                object = null; // Discard the warm up object
                runGC ();
                heap1 = usedMemory (); // Take a before heap snapshot
            }
        }
        runGC ();
        long heap2 = usedMemory (); // Take an after heap snapshot:
        
        final int size = Math.round (((float)(heap2 - heap1))/count);
        //System.out.println ("'before' heap: " + heap1 + ", 'after' heap: " + heap2);
        //System.out.println ("heap delta: " + (heap2 - heap1) + ", {" + objects [0].getClass () + "} size = " + size + " bytes");
		System.out.println(testObj + " size=" + size + " bytes");
        for (int i = 0; i < count; ++ i) objects [i] = null;
        objects = null;
    }
    private static void runGC () throws Exception
    {
        // It helps to call Runtime.gc()
        // using several method calls:
        for (int r = 0; r < 4; ++ r) _runGC ();
    }
    private static void _runGC () throws Exception
    {
        long usedMem1 = usedMemory (), usedMem2 = Long.MAX_VALUE;
        for (int i = 0; (usedMem1 < usedMem2) && (i < 500); ++ i)
        {
            s_runtime.runFinalization ();
            s_runtime.gc ();
            Thread.currentThread ().yield ();
            
            usedMem2 = usedMem1;
            usedMem1 = usedMemory ();
        }
    }
    private static long usedMemory ()
    {
        return s_runtime.totalMemory () - s_runtime.freeMemory ();
    }
    
    private static final Runtime s_runtime = Runtime.getRuntime ();
} // End of class

分别在32位和64位server上编译执行上面的程序,得到的结果:

32位server

Integer size=16 bytes
Long size=16 bytes
String size=24 bytes

64位server

Integer size=24 bytes
Long size=24 bytes
String size=40 bytes

可见,同样的class文件在不同架构的jvm执行下,会占用不同大小的内存空间。看来64位的系统也不一定好。。。

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值