我在处理中运行递归方法,但是当作业太大时,它会给我这个错误:
由于等待时发生超时,在事件线程中崩溃 包139。
但是当递归很小时它可以工作。有没有办法增加堆栈以获得更大的递归问题?
这是我的代码,用于在屏幕上绘画人物。它适用于小数字,但不适用于较大的数字。
boolean pit;
int xc;
int yc;
color negro;
color rojo;
color c;
long tiempoI;
long tiempoF;
long espera;
void setup(){
size(500,500);
negro=color(0,0,0);
negro=color(0,0,0);
rojo=#FF0000;
pit=false;
tiempoI=millis();
tiempoF=millis();
espera=5;
}
void draw(){
background(240);
noSmooth();
//dibujarRectangulo(0,0,300,300);
rect(0,0,100,100);
if(pit){
pintar(xc,yc);
}
}
void mousePressed() {
xc=mouseX;
yc=mouseY;
pit=true;
loadPixels();
c=pixels[xc+(width*yc)];
println(red(c)+" "+green(c)+" "+blue(c));
}
public void pintar(int x,int y){
if(x<width&&x>0&&y<height&&y>0){
stroke(rojo);
c=get(x,y);
if(c!=rojo&&c!=negro){
point(x,y);
}
c=get(x+1,y);
if(c!=rojo&&c!=negro){
pintar(x+1,y);
}
c=get(x-1,y);
if(c!=rojo&&c!=negro){
pintar(x-1,y);
}
c=get(x,y+1);
if(c!=rojo&&c!=negro){
pintar(x,y+1);
}
c=get(x,y-1);
if(c!=rojo&&c!=negro ){
pintar(x,y-1);
}
}
}
追溯:
由于等待时发生超时,在事件线程中崩溃 packet 139. org.eclipse.jdi.TimeoutException:发生超时 等待包139. at org.eclipse.jdi.internal.connect.PacketReceiveManager.getReply(PacketReceiveManager.java:186) 在 org.eclipse.jdi.internal.connect.PacketReceiveManager.getReply(PacketReceiveManager.java:197) 在org.eclipse.jdi.internal.MirrorImpl.requestVM(MirrorImpl.java:191) 在org.eclipse.jdi.internal.MirrorImpl.requestVM(MirrorImpl.java:226) 在 org.eclipse.jdi.internal.ThreadReferenceImpl.frames(ThreadReferenceImpl.java:257) 在 org.eclipse.jdi.internal.ThreadReferenceImpl.frames(ThreadReferenceImpl.java:240) at processing.mode.java.runner.Runner.findException(Runner.java:888) 在 processing.mode.java.runner.Runner.reportException(Runner.java:871) at processing.mode.java.runner.Runner.exceptionEvent(Runner.java:797) at processing.mode.java.runner.Runner $ 2.run(Runner.java:688) org.eclipse.jdi.TimeoutException:等待时发生超时 包140. at org.eclipse.jdi.internal.connect.PacketReceiveManager.getReply(PacketReceiveManager.java:186) 在 org.eclipse.jdi.internal.connect.PacketReceiveManager.getReply(PacketReceiveManager.java:197) 在org.eclipse.jdi.internal.MirrorImpl.requestVM(MirrorImpl.java:191) 在org.eclipse.jdi.internal.MirrorImpl.requestVM(MirrorImpl.java:226) 在 org.eclipse.jdi.internal.VirtualMachineImpl.exit(VirtualMachineImpl.java:716) 在processing.mode.java.runner.Runner.close(Runner.java:961)at processing.mode.java.JavaEditor.handleStop(JavaEditor.java:728)at at processing.mode.java.JavaToolbar.handlePressed(JavaToolbar.java:96) 在processing.app.EditorToolbar.mousePressed(EditorToolbar.java:474) 在java.awt.Component.processMouseEvent(未知来源)at javax.swing.JComponent.processMouseEvent(未知来源)at java.awt.Component.processEvent(未知来源)at java.awt.Container.processEvent(未知来源)at java.awt.Component.dispatchEventImpl(未知来源)at java.awt.Container.dispatchEventImpl(未知来源)at java.awt.Component.dispatchEvent(未知来源)at java.awt.LightweightDispatcher.retargetMouseEvent(未知来源)at java.awt.LightweightDispatcher.processMouseEvent(未知来源)at java.awt.LightweightDispatcher.dispatchEvent(未知来源)at java.awt.Container.dispatchEventImpl(未知来源)at java.awt.Window.dispatchEventImpl(未知来源)at java.awt.Component.dispatchEvent(未知来源)at java.awt.EventQueue.dispatchEventImpl(未知来源)at java.awt.EventQueue.access $ 200(未知来源)at java.awt.EventQueue $ 3.run(未知来源)at java.awt.EventQueue $ 3.run(未知来源)at java.security.AccessController.doPrivileged(Native Method)at java.security.ProtectionDomain $ 1.doIntersectionPrivilege(未知 来源)at java.security.ProtectionDomain $ 1.doIntersectionPrivilege(未知 来自)java.awt.EventQueue $ 4.run(未知来源)at java.awt.EventQueue $ 4.run(未知来源)at java.security.AccessController.doPrivileged(Native Method)at java.security.ProtectionDomain $ 1.doIntersectionPrivilege(未知 来自)java.awt.EventQueue.dispatchEvent(未知来源)at java.awt.EventDispatchThread.pumpOneEventForFilters(未知来源) at java.awt.EventDispatchThread.pumpEventsForFilter(Unknown Source) 在java.awt.EventDispatchThread.pumpEventsForHierarchy(未知 来自java.awt.EventDispatchThread.pumpEvents(未知来源) at java.awt.EventDispatchThread.pumpEvents(Unknown Source)at java.awt.EventDispatchThread.run(未知来源) org.eclipse.jdi.TimeoutException:等待时发生超时 包141. at org.eclipse.jdi.internal.connect.PacketReceiveManager.getReply(PacketReceiveManager.java:186) 在 org.eclipse.jdi.internal.connect.PacketReceiveManager.getReply(PacketReceiveManager.java:197) 在org.eclipse.jdi.internal.MirrorImpl.requestVM(MirrorImpl.java:191) 在org.eclipse.jdi.internal.MirrorImpl.requestVM(MirrorImpl.java:226) 在 org.eclipse.jdi.internal.VirtualMachineImpl.exit(VirtualMachineImpl.java:716) 在processing.mode.java.runner.Runner.close(Runner.java:961)at processing.mode.java.JavaEditor.handleStop(JavaEditor.java:728)at at processing.mode.java.JavaToolbar.handlePressed(JavaToolbar.java:96) 在processing.app.EditorToolbar.mousePressed(EditorToolbar.java:474) 在java.awt.Component.processMouseEvent(未知来源)at javax.swing.JComponent.processMouseEvent(未知来源)at java.awt.Component.processEvent(未知来源)at java.awt.Container.processEvent(未知来源)at java.awt.Component.dispatchEventImpl(未知来源)at java.awt.Container.dispatchEventImpl(未知来源)at java.awt.Component.dispatchEvent(未知来源)at java.awt.LightweightDispatcher.retargetMouseEvent(未知来源)at java.awt.LightweightDispatcher.processMouseEvent(未知来源)at java.awt.LightweightDispatcher.dispatchEvent(未知来源)at java.awt.Container.dispatchEventImpl(未知来源)at java.awt.Window.dispatchEventImpl(未知来源)at java.awt.Component.dispatchEvent(未知来源)at java.awt.EventQueue.dispatchEventImpl(未知来源)at java.awt.EventQueue.access $ 200(未知来源)at java.awt.EventQueue $ 3.run(未知来源)at java.awt.EventQueue $ 3.run(未知来源)at java.security.AccessController.doPrivileged(Native Method)at java.security.ProtectionDomain $ 1.doIntersectionPrivilege(未知 来源)at java.security.ProtectionDomain $ 1.doIntersectionPrivilege(未知 来自)java.awt.EventQueue $ 4.run(未知来源)at java.awt.EventQueue $ 4.run(未知来源)at java.security.AccessController.doPrivileged(Native Method)at java.security.ProtectionDomain $ 1.doIntersectionPrivilege(未知 来自)java.awt.EventQueue.dispatchEvent(未知来源)at java.awt.EventDispatchThread.pumpOneEventForFilters(未知来源) at java.awt.EventDispatchThread.pumpEventsForFilter(Unknown Source) 在java.awt.EventDispatchThread.pumpEventsForHierarchy(未知 来自java.awt.EventDispatchThread.pumpEvents(未知来源) at java.awt.EventDispatchThread.pumpEvents(Unknown Source)at java.awt.EventDispatchThread.run(未知来源) org.eclipse.jdi.TimeoutException:等待时发生超时 包142. at org.eclipse.jdi.internal.connect.PacketReceiveManager.getReply(PacketReceiveManager.java:186) 在 org.eclipse.jdi.internal.connect.PacketReceiveManager.getReply(PacketReceiveManager.java:197) 在org.eclipse.jdi.internal.MirrorImpl.requestVM(MirrorImpl.java:191) 在org.eclipse.jdi.internal.MirrorImpl.requestVM(MirrorImpl.java:226) 在 org.eclipse.jdi.internal.VirtualMachineImpl.exit(VirtualMachineImpl.java:716) 在processing.mode.java.runner.Runner.close(Runner.java:961)at processing.mode.java.JavaEditor.handleStop(JavaEditor.java:728)at at processing.mode.java.JavaToolbar.handlePressed(JavaToolbar.java:96) 在processing.app.EditorToolbar.mousePressed(EditorToolbar.java:474) 在java.awt.Component.processMouseEvent(未知来源)at javax.swing.JComponent.processMouseEvent(未知来源)at java.awt.Component.processEvent(未知来源)at java.awt.Container.processEvent(未知来源)at java.awt.Component.dispatchEventImpl(未知来源)at java.awt.Container.dispatchEventImpl(未知来源)at java.awt.Component.dispatchEvent(未知来源)at java.awt.LightweightDispatcher.retargetMouseEvent(未知来源)at java.awt.LightweightDispatcher.processMouseEvent(未知来源)at java.awt.LightweightDispatcher.dispatchEvent(未知来源)at java.awt.Container.dispatchEventImpl(未知来源)at java.awt.Window.dispatchEventImpl(未知来源)at java.awt.Component.dispatchEvent(未知来源)at java.awt.EventQueue.dispatchEventImpl(未知来源)at java.awt.EventQueue.access $ 200(未知来源)at java.awt.EventQueue $ 3.run(未知来源)at java.awt.EventQueue $ 3.run(未知来源)at java.security.AccessController.doPrivileged(Native Method)at java.security.ProtectionDomain $ 1.doIntersectionPrivilege(未知 来源)at java.security.ProtectionDomain $ 1.doIntersectionPrivilege(未知 来自)java.awt.EventQueue $ 4.run(未知来源)at java.awt.EventQueue $ 4.run(未知来源)at java.security.AccessController.doPrivileged(Native Method)at java.security.ProtectionDomain $ 1.doIntersectionPrivilege(未知 来自)java.awt.EventQueue.dispatchEvent(未知来源)at java.awt.EventDispatchThread.pumpOneEventForFilters(未知来源) at java.awt.EventDispatchThread.pumpEventsForFilter(Unknown Source) 在java.awt.EventDispatchThread.pumpEventsForHierarchy(未知 来自java.awt.EventDispatchThread.pumpEvents(未知来源) at java.awt.EventDispatchThread.pumpEvents(Unknown Source)at java.awt.EventDispatchThread.run(未知来源)
答案 0 :(得分:3)
你的错误确实是由过多的递归引起的StackOverflow,但是处理可以解决你所看到的奇怪错误。有关该错误的文档是here。
您可以增加Java堆栈大小以增加递归调用的限制。信息可以找到here,但要点是你必须在运行时将-Xss设置传递给Java。
但是,该设置要求您将草图作为Java应用程序运行。这是可能的,但它涉及将草图导出为jar,然后通过命令提示符运行jar,或切换到eclipse。这比简单地点击Processing中的运行按钮要多得多,而且你发送jar的任何用户都必须这样做。
相反,您应该重构算法以消除过多的递归。
答案 1 :(得分:1)
可能只是很慢。从100 x 100图像到500 x 500图像,像素数从10,000增加到250,000。这是一个很大的跳跃。而你的递归方法最终会为每个像素进行多次调用。这可能会让事情陷入困境。
要查看是否属于这种情况,请尝试逐渐增加图像大小并计算程序在图像大小增加时所需的时间。您可以预期500x500版本的速度是100x100版本的25倍。这对你来说是一个合理的执行时间吗?
如果出现这样的性能问题,请查看是否可以将其切换为迭代实现,并可能提升stroke()
调出循环。
另请注意,draw()
在循环内被调用,除非您使用noLoop()
和redraw()
控制它。你可能想在这做什么。您的draw()
可能在较大的图片上足够慢,以至于无法在其分配的时间片中运行,并且draw()
调用和事件处理正在备份。
答案 2 :(得分:0)
在获得stackoverflow异常之前,您可能会达到最大量的递归调用。我建议在Java控制面板中更改堆空间大小。
- 转到Windows中的“控制面板”。
- 点击Java。
- 转到Java选项卡,然后单击View。
- 您将看到一个名为Runtime Parameters的部分。双击该列(确保双击您的版本 目前正在使用)。这将允许您编辑它。
有几种方法可以设置堆大小。我会列出它们:
-Xms<size> set initial Java heap size -Xmx<size> set maximum Java heap size -Xss<size> set java thread stack size
- 醇>
例如,我已将我的设置为:-Xms512m。不要忘记应用/保存所做的更改。
对于Eclipse,您还可以设置堆空间:
- 在“运行” - >“运行配置”中,找到您所在班级的名称 运行,选择它,单击Arguments选项卡,然后将:-Xms512M -Xmx1524M添加到VM Arguments部分
醇>
答案 3 :(得分:0)
递归时可能超过堆栈。你的树不应该太深。请参阅here。
但是,基于您的堆栈跟踪和您提供问题的代码不在代码的这一部分中。它看起来,基于堆栈跟踪,你递归调用一些GUI方法或鼠标事件处理方法而不是方法pintar()。