我正在spoj
解决问题,系统显示我的程序占用了1341M
内存。当我查看其他语言的提交时,他们需要~3M
,这要少约400倍!
我的代码如下:
class Main {
static List<BigInteger> numbers = new ArrayList<>();
static {
BigInteger max = BigInteger.TEN.pow(100);
numbers.add(BigInteger.ONE);
numbers.add(BigInteger.valueOf(2l));
BigInteger last = numbers.get(1);
while (last.compareTo(max) <= 0) {
numbers.add(numbers.get(numbers.size() - 1).add(numbers.get(numbers.size() - 2)));
last = numbers.get(numbers.size() - 1);
}
}
public static void main(String[] args) throws java.lang.Exception {
BufferedReader bi = new BufferedReader(new InputStreamReader(System.in));
String line;
String delims = " ";
while ((line = bi.readLine()) != null) {
StringTokenizer tokenizer = new StringTokenizer(line, delims);
BigInteger from = new BigInteger(tokenizer.nextToken());
BigInteger to = new BigInteger(tokenizer.nextToken());
if (from.equals(BigInteger.ZERO) && to.equals(BigInteger.ZERO)) {
return;
} else {
System.out.println(countInRange(from, to));
}
}
}
public static int countInRange(BigInteger from, BigInteger to) {
int fromIndex = Collections.binarySearch(numbers, from);
fromIndex = fromIndex < 0 ? Math.abs(fromIndex) - 1 : fromIndex;
int toIndex = Collections.binarySearch(numbers, to);
toIndex = toIndex < 0 ? Math.abs(toIndex) - 1 : toIndex + 1;
return toIndex - fromIndex;
}
}
我认为BufferedReader
是高内存消耗的原因。在这种情况下,是否有可能显着改善内存占用?我不是在谈论实现3M
,而是至少在100M
左右。
答案 0 :(得分:1)
首先关闭:您如何保留numbers
中的元素?可能会有一些,因为你的最大值是10 pow 100。
第二:考虑Java内存模型。 1341M大约适合32位Java VM。所以也许只是你在堆上生成对象(所有这些闪亮的new BigInteger
),Java产生了大量的垃圾内存。但是,如果您没有为您的流程设置正确的选项,则不会将其返回给操作系统。
您是否尝试运行只有100M内存的程序(通过在java调用中设置-Xmx100m
选项?
考虑创建一个堆转储并检查一下(我建议Eclipse Memory Profiler看看你的记忆是什么。我最好的猜测是:它是大量预先计算的数字(它们是什么) ?对我来说,似乎是一个卢卡斯序列?)或只是垃圾等待收集。
答案 1 :(得分:1)
快速检查:您确定IDE实际上没有使用1341MB内存(例如Eclipse或Netbeans)吗?
我将代码打包到一个可执行的Jar中,在具有64b Oracle JRE 1.8.0.66的Windows 7 x64机器上。运行代码时,系统仅显示大约10MB的内存消耗。我使用:
生成了一个堆转储java -agentlib:hprof=file=snapshot.hprof,format=b -jar number_counter.jar
使用Eclipse Memory Analyzer进行分析时,使用过的对象的内存占用率非常低。
一些注意事项:
要结束,请检查您是否正在监控正确的Java进程,请确保使用最新的JRE并确保不使用某些不必要的内存管理规则。您的代码似乎很好,占用空间应小于20 MB。