首页 > 解决方案 > 如何减少java中的RAM使用?

问题描述

报表数据库类

public class ReportDatabase {

    private static final Map<String, Report> reportTypes;
    private static final String[] reportTypeNameVersion = {
            "Payroll Tax Report 1",
            "Capital Gains Tax Report 1",
            "Overall Expenditure Report 1",
            "Dark Costs Report 1",
            "Petty Cash Report 1",
            "Enron Fund Report 1",
            "COVID-19 Report 1",
            "COVID-20 Report 1",
            "Brawndo Investment Report 1",
            "Philanthropy Report 1",
            "Payroll Tax Report 2",
            "Capital Gains Tax Report 2",
            "Overall Expenditure Report 2",
            "Dark Costs Report 2",
            "Petty Cash Report 2",
            "Enron Fund Report 2",
            "COVID-19 Report 2",
            "COVID-20 Report 2",
            "Brawndo Investment Report 2",
            "Philanthropy Report 2"
    };

    static {
        reportTypes = new HashMap<>();

        for (String name: reportTypeNameVersion) {
            reportTypes.put(name, new ReportImpl(name.substring(0, name.length()-1), getReportCommission(), getReportData(), getReportData(), getReportData(), getReportData(), getReportData()));
        }
    }

    /**
     * Note from Tim:
     * The version number is entirely arbitrary and not used anywhere else, so we can't use it as a composite key...
     * There are also more than 2 versions per name in the full system.
     *
     * The recreation/copying here is simulating a networked database connection
     */
    public static Collection<Report> getTestReports() {

        Collection<Report> originals = reportTypes.values();
        List<Report> result = new ArrayList<>();

        for (Report original: originals) {
            result.add(new ReportImpl(original.getReportName(),
                    original.getCommission(),
                    original.getLegalData().clone(),
                    original.getCashFlowData().clone(),
                    original.getMergesData().clone(),
                    original.getTallyingData().clone(),
                    original.getDeductionsData().clone()));
        }

        return result;
    }

    private static double[] getReportData() {

        /*
        Note from Tim:
        If your machine's memory can't handle the whole product data, you could set this lower while you work out
        a way to stop the RAM explosion? We do need to be able to get at the whole product though.
        The database doesn't though...
         */

        double[] result = new double[500000];
        Random random = new Random();

        for (int i = 0; i < result.length; i++) {
            result[i] = random.nextDouble();
        }

        return result;
    }

    private static double getReportCommission() {
        Random random = new Random();

        return 1.0 + 99.0 * random.nextDouble();
    }
}

ReportImpl 类:

import au.edu.sydney.cpa.erp.ordering.Report;

public class ReportImpl implements Report {

    private String name;
    private double commissionPerEmployee;
    private double[] legalData;
    private double[] cashFlowData;
    private double[] mergesData;
    private double[] tallyingData;
    private double[] deductionsData;

    public ReportImpl(String name,
                      double commissionPerEmployee,
                      double[] legalData,
                      double[] cashFlowData,
                      double[] mergesData,
                      double[] tallyingData,
                      double[] deductionsData) {
        this.name = name;
        this.commissionPerEmployee = commissionPerEmployee;
        this.legalData = legalData;
        this.cashFlowData = cashFlowData;
        this.mergesData = mergesData;
        this.tallyingData = tallyingData;
        this.deductionsData = deductionsData;
    }

    @Override
    public String getReportName() {
        return name;
    }

    @Override
    public double getCommission() {
        return commissionPerEmployee;
    }

    @Override
    public double[] getLegalData() {
        return legalData;
    }

    @Override
    public double[] getCashFlowData() {
        return cashFlowData;
    }

    @Override
    public double[] getMergesData() {
        return mergesData;
    }

    @Override
    public double[] getTallyingData() {
        return tallyingData;
    }

    @Override
    public double[] getDeductionsData() {
        return deductionsData;
    }

    @Override
    public String toString() {

        return String.format("%s", name);
    }
}

类中的方法,调用方法,从ReportDatabase类getTestReports()

public List<Report> getAllReports() {
        if (null == token) {
            throw new SecurityException();
        }

        return new ArrayList<>(ReportDatabase.getTestReports());
    }

对于上述类,我需要减少 RAM 使用量,规则是,我需要使用 ReportDatabase.getTestReports(),并且我不能修改 ReportDatabase 类中的任何内容(仅限)。如果我打印出 RAM 消耗,大约是 450MB。我尝试创建一个 ReportFactory 类以应用享元模式,但我认为实例化 ReportDatabase 类以直接使用 getTestReports 需要大约 400MB RAM 消耗,因为:

有 20 个报告,每个报告有 6 个双数组。每个数组有 500000 个双精度数。如果我们计算内存,java中的double数是8个字节。总内存将是

8⋅500000⋅6⋅20/(1024⋅1024)≈450MB

我应该如何减少上述类的 RAM 使用量?我可以得到任何提示吗?

标签: javamemoryramflyweight-pattern

解决方案


推荐阅读