欢迎您访问程序员文章站本站旨在为大家提供分享程序员计算机编程知识!
您现在的位置是: 首页

性能调优实战案例2-对某段代码内存的计算

程序员文章站 2022-05-06 14:34:32
...

性能调优实战案例2-对某段代码内存的计算

1、问题

有一个查询,一次性将50万条记录查询、加载到内存中。如何通过JVM监控和根据一些监控数据推理出这50万条数据大概占用的内存大小?

2、分析

2.1、最直接的思路如下:

第一步,先取得加载数据前的内存大小

第二步,加载数据到内存中

第三步,再取得加载数据后的内存大小

第四步,求前后内存的差值

简单来说,在Java中就是load数据前后,堆大小的比较。

3、解决方案

3.1、java.lang.management.MemoryMXBean

package memorymxbean;

import java.lang.management.ManagementFactory;
import java.lang.management.MemoryMXBean;
import java.lang.management.MemoryUsage;
import java.util.ArrayList;
import java.util.List;

/**
 * @ClassName Main
 * @Description TODO 类作用描述
 * @Author Dave Ding
 * @CreateDate 2019/7/11 19:03
 * @Version V1.0
 **/
public class Main {
    public static void main(String[] args){

        MemoryMXBean mbean = ManagementFactory.getMemoryMXBean();
        MemoryUsage m = mbean.getHeapMemoryUsage();
        long start = m.getUsed();
        System.out.println("-------------------开始统计内存:"+start);

        // 业务代码
        List list = new ArrayList<Integer>();
        for(int i=0;i<500000;i++){
            list.add(i);
        }

        mbean = ManagementFactory.getMemoryMXBean();
        m = mbean.getHeapMemoryUsage();
        long end = m.getUsed();
        System.out.println("-------------------结束统计内存:"+end);
        System.out.println("-------------------差值:"+(end-start));
    }
}

3.2、jvisualvm

步骤:

程序稳定运行5-10分钟后,打开jvisualvm,连接上运行程序的tomcat,接着执行一次GC,记录下GC后已使用的堆大小a,然后执行一下加载数据的操作,然后观察内存的变化,记录下此时堆大小的峰值b,两个值求差。重复测试10次左右,取差值之和的平均值。这个值大概就是这批数据的堆大小了。

存在问题

当数据量较小时,取得平均值不准确。

3.3、jmx

3.4、arthas

3.5、其它

(1)根据表结构计算

(2)根据String对象中char的大小计算

不过这两种方法需要计算,而且不能简单地累加。暂时没有研究。

3、延伸思考

3.1、Java一下子将50万条数据加载到内存中,会造成什么问题?

  • 加大服务器内存压力
  • 内存溢出问题

3.2、Java导出Excel数据量过大(50万以上)内存溢出如何解决?

  • 用临时文件,先写在临时文件中,在写入excel中
  • 多文件打包
  • xml转Excel
  • 多sheet

4、参考

(1)https://bbs.csdn.net/topics/390924117?page=1

(2)MemoryMXBean:https://blog.csdn.net/liuwei_csd/article/details/83327782

(3)arthas:https://blog.csdn.net/xiao_jun_0820/article/details/82774796

(4)jmx:https://www.jianshu.com/p/fa4e88f95631

(5)Java计算一个对象占用内存的大小:

https://blog.csdn.net/bobpauline/article/details/20699233

https://www.cnblogs.com/E-star/p/10222250.html

(6)换算工具

相关标签: 性能调优 JVM