在NetLogo 3D中具有非常大的世界的错误(ArrayIndexOutOfBoundsException)

时间:2014-04-17 08:11:56

标签: 3d netlogo

当我开始使用Netlogo构建3D模型时,首先我将3D模型设置更改为2000 * 2000 * 500,这是我需要的尺寸。 然后我写了一个非常简单的测试代码。

breed [airs air]

to setup
  clear-all
  create-airs 1 [
    set color pink
    setxyz 1000 1000 250
    set heading 0
    set pitch 0
  ]
end  

然后我尝试运行setup命令,出现运行时错误。

error (ArrayIndexOutOfBoundsException)
 while observer running CREATE-AIRS
  called by procedure SETUP
  called by Button 'setup'

NetLogo is unable to supply you with more details about this error.  Please report the problem
at https://github.com/NetLogo/NetLogo/issues, or to bugs@ccl.northwestern.edu, and paste the
contents of this window into your report.

java.lang.ArrayIndexOutOfBoundsException: 2006002500
 at org.nlogo.agent.World3D.getPatchAtWrap(World3D.java:159)
 at org.nlogo.agent.Turtle3D.getPatchHere(Turtle3D.java:183)
 at org.nlogo.agent.Turtle3D.<init>(Turtle3D.java:88)
 at org.nlogo.agent.Turtle3D.<init>(Turtle3D.java:62)
 at org.nlogo.agent.World3D.createTurtle(World3D.java:401)
 at org.nlogo.prim._createturtles.perform(_createturtles.java:51)
 at org.nlogo.nvm.Context.stepConcurrent(Context.java:91)
 at org.nlogo.nvm.ConcurrentJob.step(ConcurrentJob.java:82)
 at org.nlogo.job.JobThread.org$nlogo$job$JobThread$$runPrimaryJobs(JobThread.scala:143)
 at org.nlogo.job.JobThread$$anonfun$run$1.apply$mcV$sp(JobThread.scala:78)
 at org.nlogo.job.JobThread$$anonfun$run$1.apply(JobThread.scala:76)
 at org.nlogo.job.JobThread$$anonfun$run$1.apply(JobThread.scala:76)
 at scala.util.control.Exception$Catch.apply(Exception.scala:88)
 at org.nlogo.util.Exceptions$.handling(Exceptions.scala:41)
 at org.nlogo.job.JobThread.run(JobThread.scala:75)

NetLogo 3D 5.0.5
main: org.nlogo.app.AppFrame
thread: JobThread
Java HotSpot(TM) Server VM 1.6.0_45 (Sun Microsystems Inc.; 1.6.0_45-b06)
operating system: Windows 8 6.2 (x86 processor)
Scala version 2.9.2
JOGL: 1.1.1
OpenGL graphics: Intel(R) HD Graphics 4400
OpenGL version: 4.2.0 - Build 10.18.10.3316
OpenGL vendor: Intel
model: airsimul

03:53:42.404 SwitchedTabsEvent (org.nlogo.app.Tabs) AWT-EventQueue-0
03:53:42.400 RuntimeErrorEvent (org.nlogo.app.App$$anon$1 (org.nlogo.window.GUIWorkspace)) AWT-EventQueue-0
03:53:42.392 JobRemovedEvent (org.nlogo.app.App$$anon$1 (org.nlogo.window.GUIWorkspace)) JobThread
03:53:42.391 PeriodicUpdateEvent (org.nlogo.app.App$$anon$1 (org.nlogo.window.GUIWorkspace)) AWT-EventQueue-0
03:53:42.391 TickStateChangeEvent (org.nlogo.app.App$$anon$1 (org.nlogo.window.GUIWorkspace)) JobThread
03:53:42.391 OutputEvent (org.nlogo.app.App$$anon$1 (org.nlogo.window.GUIWorkspace)) AWT-EventQueue-0
03:53:42.386 AddJobEvent (org.nlogo.window.ButtonWidget) AWT-EventQueue-0
03:53:42.261 InputBoxLoseFocusEvent (org.nlogo.window.ButtonWidget) AWT-EventQueue-0
03:53:42.212 PeriodicUpdateEvent (org.nlogo.app.App$$anon$1 (org.nlogo.window.GUIWorkspace)) AWT-EventQueue-0
03:53:42.011 PeriodicUpdateEvent (org.nlogo.app.App$$anon$1 (org.nlogo.window.GUIWorkspace)) AWT-EventQueue-0

任何人都可以告诉我这是关于什么的吗?

1 个答案:

答案 0 :(得分:0)

请参阅How to model a very large world in NetLogo?http://ccl.northwestern.edu/netlogo/docs/faq.html#howbig和re:Windows,https://github.com/NetLogo/NetLogo/issues/423

(虽然我无法解释为什么你得到ArrayIndexOutOfBoundsException而不是我期望的OutOfMemoryError。你在得到前者之前得到了后者吗?)

NetLogo中的内存使用量与代理数量成正比。你的世界有多少补丁?您关于世界规模的陈述有点含糊不清。如果您启动NetLogo并在对话框中键入2000,2000和500,则生成的世界为4001 * 4001 * 1001,因为您输入的数字是最大值,但补丁坐标也可能是负数。

4001 * 4001 * 1001是160亿补丁。默认情况下,NetLogo的堆大小为1 GB。我刚才进行了实验,发现在这个内存量上我可以有大约200万个补丁。 (并且这不是试图对补丁做任何事情,而是首先创建它们;实际上用它们做任何事情都需要额外的内存。多少取决于我在做什么。)

如果一个千兆字节的RAM容纳大约200万个补丁,那么要有160亿个补丁,那么你将需要8TB的RAM。换句话说,你正在努力的规模是非常不现实的。

<强>更新

关于你为什么得到ArrayIndexOutOfBoundsException而不是OutOfMemoryError的问题,我现在有了一个理论。

在NetLogo中,补丁存储在一个大数组中。在JVM上,数组不能超过2147483647(~21亿)元素,因为数组索引是带符号的32位整数。当NetLogo 3D创建补丁阵列时,它会new Patch[worldWidth * worldHeight * worldDepth]。因为JVM在整数操作上没有检测到溢出,所以您可能得到错误的答案,例如在Java 2000 * 2000 * 8000中等于1935228928(?!)。如果您尝试创建的世界维度足够大,整数溢出可能会导致NetLogo计算补丁数组的大小不正确。然后,补丁阵列的创建可能会成功,但是一些尝试访问补丁的操作会因ArrayIndexOutOfBoundsException而失败,因为该数组对于提供的世界维度来说太小了。

请注意,只有当您尝试的世界大小超出了可能的范围时,才会发生这种情况。 21亿个补丁需要大约1TB的RAM,无论你使用的是32位还是64位发射器,它都不会起作用。