解决Java运行内存限制的问题,issue #23

- 在judger中增加MEMORY_UNLIMITED的选项,不再限制Java内存分配了。刚刚提交上去 QingdaoU/Judger@2577bec
 - 将内存限制加入到Xmx等参数上,如果Java代码运行超过这个内存限制会导致异常
 - 如果没有异常,就在Python逻辑中比较题目限制的内存与judger获取Java运行时占用的内存(这个内存是准确的,比如a+b一般是20M左右),判断是否是超内存。
This commit is contained in:
virusdefender 2016-03-31 21:30:18 +08:00
parent 078170a761
commit 847c82a500
2 changed files with 26 additions and 6 deletions

View File

@ -32,7 +32,21 @@ class JudgeClient(object):
self._language = languages[language_code]
self._exe_path = exe_path
self._max_cpu_time = max_cpu_time
self._max_memory = max_memory
# 如果是Java, 就不在judger中限制内存分配了, 而是转移到Java运行参数中,
# 参见 https://github.com/QingdaoU/OnlineJudge/issues/23
# 这里给出3倍的限制, 是为了防止出现OutOfMemory异常导致误判为Runtime Error,
# 如果实际使用超过了3倍, 就只能得到Runtime Error的结果了
# 而最后会比较Java实际使用的内存和1.5倍的设定内存的大小
self._real_max_memory = max_memory
if self._language["name"] == "java":
self._max_memory = judger.MEMORY_UNLIMITED
self.execute_command = self._language["execute_command"].\
format(exe_path=self._exe_path, max_memory=max_memory * 3).split(" ")
else:
self._max_memory = self._real_max_memory
self.execute_command = self._language["execute_command"].format(exe_path=self._exe_path).split(" ")
self._test_case_dir = test_case_dir
# 进程池
self._pool = Pool(processes=max_running_number)
@ -82,18 +96,22 @@ class JudgeClient(object):
return output_md5, output_md5 == test_case_config["striped_output_md5"]
def _judge_one(self, test_case_id):
execute_command = self._language["execute_command"].format(exe_path=self._exe_path).split(" ")
run_result = judger.run(path=execute_command[0],
run_result = judger.run(path=self.execute_command[0],
max_cpu_time=self._max_cpu_time,
max_memory=self._max_memory,
in_file=os.path.join(self._test_case_dir, str(test_case_id) + ".in"),
out_file=os.path.join(self._judge_base_path, str(test_case_id) + ".out"),
args=execute_command[1:],
args=self.execute_command[1:],
env=["PATH=" + os.environ["PATH"]],
use_sandbox=self._language["use_sandbox"],
use_nobody=True)
run_result["test_case"] = test_case_id
# 对Java的特殊处理, 详见__init__函数中注释
if self._language["name"] == "java" and run_result["memory"] > self._real_max_memory * 1.5:
run_result["flag"] = 3
# 将judger返回的结果标志转换为本系统中使用的
if run_result["flag"] == 0:
output_md5, r = self._compare_output(test_case_id)
if r:

View File

@ -23,7 +23,9 @@ languages = {
"src_name": "Main.java",
"code": 3,
"compile_command": "/usr/bin/javac {src_path} -d {exe_path} -encoding UTF8",
"execute_command": "/usr/bin/java -cp {exe_path} -Djava.security.manager -Djava.security.policy==policy Main",
"execute_command": "/usr/bin/java -cp {exe_path} -Xss1M -XX:MaxPermSize=16M "
"-XX:PermSize=8M -Xms16M -Xmx{max_memory} -Djava.security.manager "
"-Djava.security.policy==policy -Djava.awt.headless=true Main",
"use_sandbox": False
}
}