前言

最近在公司需要对导出各种类型的报表进行一个性能优化(主要是防止溢出),然后要对性能优化的话肯定要先对当前的性能进行排查,然后对于这篇文章的话主要是写个开头,说明一下如何计算JAVA对象的内存占用大小

目录

1.对象占用内存的基本组成结构
2.对象的占用内存计算
3.第三方内存大小计算工具

对象占用内存的基本组成结构

java进程内存占用 java 内存占用_性能优化

对象内存占用计算

以下面类为例

class People{
   int age = 20;
   String name = "Xiaoming";
}
class Person extends People{
    boolean married = false;
    long birthday = 128902093242L;
    char tag = 'c';
    double sallary = 1200.00d;
}

计算Person的内存占用对象(bytes),例子用32位计算器(若64位且不指针压缩则需要重新计算mark word和引用对象)

实例数据:

对象头:
4(mark) + 4(klass) = 8
实例数据:
4(age) + 4(name(ref)) + 1(married) + 8(birthday) + 2(tag) + 8(sallary) = 27
要注意的是,name为引用类型,还需要计算引用类型的实际大小

// 然后String源码又是这样的
/** The value is used for character storage. */
private final char value[];
 
/** Cache the hash code for the string */
private int hash; // Default to 0
 
/** use serialVersionUID from JDK 1.0.2 for interoperability */
private static final long serialVersionUID = -6849794470754667710L;

并且字符串又是引用char[]数组进行计算的,则也要继续往下计算
name表层:对象头8个字节 + hash(4) + serialVersionUID(8) + 4(char[]) = 24
然后计算char[] = 对象头8个字节 +数组的length(4) + char(2) * 8 = 28

目前Person总大小为
对象头 + 实例数据 = 87
然后由于字段的需要是8个字节的倍数,所以需要计算padding
总大小为: 对象头 + 实例数据 + padding = 88

第三方内存大小计算工具

以计算CellData对象为例(自己产品的对象)
1.编写main方法创建对象

public class testCalc {
	
	public static void main (String[] args) throws InterruptedException {
		CellData cellData = new CellData();
		System.out.println("启动开始计算");
		// 这个sleep就是为了当前java线程一直存在
		Thread.sleep(1000 * 3600);
        System.out.println(cellData);
	}
}

2.打开cmd,找到当前执行的java线程

直接在cmd中输入 jsp找到当前线程编号

java进程内存占用 java 内存占用_java线程_02


3.打开HSDB工具

找到路径jdk\lib,在当前路径打开cmd,输入

java进程内存占用 java 内存占用_数据_03


4.在HSDB中打开当前java线程

java进程内存占用 java 内存占用_数据_04


注意:若出现以下两个问题,相对应解决就好

1.Exception in thread “Thread-1” java.lang.UnsatisfiedLinkError: Can’t load library: JRE_PATH\bin\sawindbg.dll

     解决方法:从jdk/jre/bin/下面复制一个sawindbg.dll到jre/bin路径下即可

2.could not fined symol ‘gHotSpotVMTypes’

     解决方法:这个时候就是说明你运行类的jdk和你环境变量的jdk版本不一样,比如你运行类的jdk为1.7,但是环境变量的jdk为1.8,这个时候就会版本不对称导致出现错误了,把版本弄成一样的就好了

5.使用tool找到当前类

java进程内存占用 java 内存占用_java_05


java进程内存占用 java 内存占用_数据_06


java进程内存占用 java 内存占用_性能优化_07


java进程内存占用 java 内存占用_数据_08


java进程内存占用 java 内存占用_java线程_09