【问题标题】:When Will Storage Requirements Exceed RAM in a System that Constantly Computes Higher Values and Stores Them on the Disk?在不断计算更高值并将其存储在磁盘上的系统中,存储需求何时会超过 RAM?
【发布时间】:2014-10-20 05:03:23
【问题描述】:

我正在做一个可以产生无限数量的数字的项目 <More on this>: Threading Isues With Fixed Thread Pool and Large Number of Tasks 我已经成功地解决了它所涉及的线程问题。另外,我决定将排序器的结果存储在硬盘上,这样我就可以计算更多的数字(并确保它们都收敛到 1),每次存储结果的HashMap 达到时我都会这样做400,000(我的电脑上一个合理的大小,大约 1GB/8GB)键/值对,然后加载下一个 400,000。假设值是FinalSequencerReports,随着值越来越大,趋向于∞,存储的值最终应该会超过我的 RAM 容量,有没有办法绕过这个限制(或者甚至是多少我会甚至会遇到存储400,000 实例将超出我的RAM 容量的情况?或者任何RAM 容量的公式?)注意:在FinalSequencerReport 类中有一个String,它将始终为空。

类被存储在HashMap<BigInteger, FinalSequencerReport<BigInteger>>:

public static final class FinalSequencerReport<T extends Number> extends SequencerReport<T> implements Comparable<FinalSequencerReport<T>> {

    public static Comparator<? super FinalSequencerReport<? extends Number>> compareByInitialValue() {
        return (FinalSequencerReport<? extends Number> o1, FinalSequencerReport<? extends Number> o2)
                -> new BigInteger(o1.getInitialValue().toString()).compareTo(new BigInteger(o2.getInitialValue().toString()));
    }
    private final T initialValue;
    private final String finalFormattedString;

    public FinalSequencerReport(SequencerReport<T> finalReport, T initialValue) {
        super(finalReport.getResult(), finalReport.getIterations(), finalReport.getSequence());
        this.initialValue = initialValue;
        this.finalFormattedString = "Initial Value: "
                + getInitialValue() + "\nFinal Value: " + getResult() + "\nIterations:  "
                + getIterations() + "\nAlgebraic Sequence:\n" + getSequence();
    }

    public String getFinalFormattedString() {
        return this.finalFormattedString;
    }

    public Number getInitialValue() {
        return this.initialValue;
    }

    @Override
    public int compareTo(FinalSequencerReport<T> o) {
        return FinalSequencerReport.compareByInitialValue().compare(this, o);
    }
}

public static class SequencerReport<T extends Number> {

    private final T result, iterations;
    private final String sequence;

    public SequencerReport(T result, T iterations) {
        this(result, iterations, "");
    }

    public SequencerReport(T result, T iterations, String sequence) {
        this.result = result;
        this.iterations = iterations;
        this.sequence = sequence;
    }

    public T getResult() {
        return this.result;
    }

    public T getIterations() {
        return this.iterations;
    }

    public String getSequence() {
        return this.sequence;
    }

}

【问题讨论】:

  • 如果您按顺序计算所有结果,那么没有理由使用BigInteger,因为在合理的时间内离开long 范围没有任何变化。请注意,BigInteger 会大大降低计算速度。

标签: java multithreading performance math recursion


【解决方案1】:

您需要定期check the available HDD space,与RAM check 配对 - 我建议您比 HDD 更频繁地检查 RAM。

如果您想估计空间使用情况,您可以approximate the size of your objects,但请注意:由于对象的内部表示可能随时更改,您可能会得到不正确的结果,这是特定于实现的,对象大小不能准确在java中测量,AFAIK

另外请注意,可用 RAM 的上限始终取决于您的 JVM 设置,Oracle-JVM 设置可以通过-Xmx 更改,可能的后缀包括m 和g,例如:-Xmx2g -不要摆弄-Xms,因为如果不产生奇怪的崩溃,它会严重减慢一切,因为你有效地规避了每个 JVM 优化

可用文件系统空间和可用 RAM:

 /* Total number of processors or cores available to the JVM */
  System.out.println("Available processors (cores): " + 
  Runtime.getRuntime().availableProcessors());

  /* Total amount of free memory available to the JVM */
  System.out.println("Free memory (bytes): " + 
  Runtime.getRuntime().freeMemory());

  /* This will return Long.MAX_VALUE if there is no preset limit */
  long maxMemory = Runtime.getRuntime().maxMemory();
  /* Maximum amount of memory the JVM will attempt to use */
  System.out.println("Maximum memory (bytes): " + 
  (maxMemory == Long.MAX_VALUE ? "no limit" : maxMemory));

  /* Total memory currently in use by the JVM */
  System.out.println("Total memory (bytes): " + 
  Runtime.getRuntime().totalMemory());

  /* Get a list of all filesystem roots on this system */
  File[] roots = File.listRoots();

  /* For each filesystem root, print some info */
  for (File root : roots) {
    System.out.println("File system root: " + root.getAbsolutePath());
    System.out.println("Total space (bytes): " + root.getTotalSpace());
    System.out.println("Free space (bytes): " + root.getFreeSpace());
    System.out.println("Usable space (bytes): " + root.getUsableSpace());
  }

物体大小近似:

import java.lang.instrument.Instrumentation;

public class ObjectSizeFetcher {
    private static Instrumentation instrumentation;

    public static void premain(String args, Instrumentation inst) {
        instrumentation = inst;
    }

    public static long getObjectSize(Object o) {
        return instrumentation.getObjectSize(o);
    }
}

public class C {
    private int x;
    private int y;

    public static void main(String [] args) {
        System.out.println(ObjectSizeFetcher.getObjectSize(new C()));
    }
}

【讨论】:

    猜你喜欢
    • 2012-05-13
    • 2012-08-02
    • 1970-01-01
    • 2011-06-08
    • 2014-06-10
    • 2012-07-29
    • 1970-01-01
    • 2011-10-04
    • 2010-09-15
    相关资源
    最近更新 更多