如何增加堆栈大小以允许更多递归?
How to increase stack size to allow more recursion?
我是运行在处理递归方法,但是当作业太大的时候,报错:
crashed in event thread due to Timeout occurred while waiting for
packet 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);
}
}
}
回溯:
crashed in event thread due to Timeout occurred while waiting for
packet 139. org.eclipse.jdi.TimeoutException: Timeout occurred while
waiting for packet 139. at
org.eclipse.jdi.internal.connect.PacketReceiveManager.getReply(PacketReceiveManager.java:186)
at
org.eclipse.jdi.internal.connect.PacketReceiveManager.getReply(PacketReceiveManager.java:197)
at org.eclipse.jdi.internal.MirrorImpl.requestVM(MirrorImpl.java:191)
at org.eclipse.jdi.internal.MirrorImpl.requestVM(MirrorImpl.java:226)
at
org.eclipse.jdi.internal.ThreadReferenceImpl.frames(ThreadReferenceImpl.java:257)
at
org.eclipse.jdi.internal.ThreadReferenceImpl.frames(ThreadReferenceImpl.java:240)
at processing.mode.java.runner.Runner.findException(Runner.java:888)
at
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.run(Runner.java:688)
org.eclipse.jdi.TimeoutException: Timeout occurred while waiting for
packet 140. at
org.eclipse.jdi.internal.connect.PacketReceiveManager.getReply(PacketReceiveManager.java:186)
at
org.eclipse.jdi.internal.connect.PacketReceiveManager.getReply(PacketReceiveManager.java:197)
at org.eclipse.jdi.internal.MirrorImpl.requestVM(MirrorImpl.java:191)
at org.eclipse.jdi.internal.MirrorImpl.requestVM(MirrorImpl.java:226)
at
org.eclipse.jdi.internal.VirtualMachineImpl.exit(VirtualMachineImpl.java:716)
at processing.mode.java.runner.Runner.close(Runner.java:961) at
processing.mode.java.JavaEditor.handleStop(JavaEditor.java:728) at
processing.mode.java.JavaToolbar.handlePressed(JavaToolbar.java:96)
at processing.app.EditorToolbar.mousePressed(EditorToolbar.java:474)
at java.awt.Component.processMouseEvent(Unknown Source) at
javax.swing.JComponent.processMouseEvent(Unknown Source) at
java.awt.Component.processEvent(Unknown Source) at
java.awt.Container.processEvent(Unknown Source) at
java.awt.Component.dispatchEventImpl(Unknown Source) at
java.awt.Container.dispatchEventImpl(Unknown Source) at
java.awt.Component.dispatchEvent(Unknown Source) at
java.awt.LightweightDispatcher.retargetMouseEvent(Unknown Source) at
java.awt.LightweightDispatcher.processMouseEvent(Unknown Source) at
java.awt.LightweightDispatcher.dispatchEvent(Unknown Source) at
java.awt.Container.dispatchEventImpl(Unknown Source) at
java.awt.Window.dispatchEventImpl(Unknown Source) at
java.awt.Component.dispatchEvent(Unknown Source) at
java.awt.EventQueue.dispatchEventImpl(Unknown Source) at
java.awt.EventQueue.access0(Unknown Source) at
java.awt.EventQueue.run(Unknown Source) at
java.awt.EventQueue.run(Unknown Source) at
java.security.AccessController.doPrivileged(Native Method) at
java.security.ProtectionDomain.doIntersectionPrivilege(Unknown
Source) at
java.security.ProtectionDomain.doIntersectionPrivilege(Unknown
Source) at java.awt.EventQueue.run(Unknown Source) at
java.awt.EventQueue.run(Unknown Source) at
java.security.AccessController.doPrivileged(Native Method) at
java.security.ProtectionDomain.doIntersectionPrivilege(Unknown
Source) at java.awt.EventQueue.dispatchEvent(Unknown Source) at
java.awt.EventDispatchThread.pumpOneEventForFilters(Unknown Source)
at java.awt.EventDispatchThread.pumpEventsForFilter(Unknown Source)
at java.awt.EventDispatchThread.pumpEventsForHierarchy(Unknown
Source) at java.awt.EventDispatchThread.pumpEvents(Unknown Source)
at java.awt.EventDispatchThread.pumpEvents(Unknown Source) at
java.awt.EventDispatchThread.run(Unknown Source)
org.eclipse.jdi.TimeoutException: Timeout occurred while waiting for
packet 141. at
org.eclipse.jdi.internal.connect.PacketReceiveManager.getReply(PacketReceiveManager.java:186)
at
org.eclipse.jdi.internal.connect.PacketReceiveManager.getReply(PacketReceiveManager.java:197)
at org.eclipse.jdi.internal.MirrorImpl.requestVM(MirrorImpl.java:191)
at org.eclipse.jdi.internal.MirrorImpl.requestVM(MirrorImpl.java:226)
at
org.eclipse.jdi.internal.VirtualMachineImpl.exit(VirtualMachineImpl.java:716)
at processing.mode.java.runner.Runner.close(Runner.java:961) at
processing.mode.java.JavaEditor.handleStop(JavaEditor.java:728) at
processing.mode.java.JavaToolbar.handlePressed(JavaToolbar.java:96)
at processing.app.EditorToolbar.mousePressed(EditorToolbar.java:474)
at java.awt.Component.processMouseEvent(Unknown Source) at
javax.swing.JComponent.processMouseEvent(Unknown Source) at
java.awt.Component.processEvent(Unknown Source) at
java.awt.Container.processEvent(Unknown Source) at
java.awt.Component.dispatchEventImpl(Unknown Source) at
java.awt.Container.dispatchEventImpl(Unknown Source) at
java.awt.Component.dispatchEvent(Unknown Source) at
java.awt.LightweightDispatcher.retargetMouseEvent(Unknown Source) at
java.awt.LightweightDispatcher.processMouseEvent(Unknown Source) at
java.awt.LightweightDispatcher.dispatchEvent(Unknown Source) at
java.awt.Container.dispatchEventImpl(Unknown Source) at
java.awt.Window.dispatchEventImpl(Unknown Source) at
java.awt.Component.dispatchEvent(Unknown Source) at
java.awt.EventQueue.dispatchEventImpl(Unknown Source) at
java.awt.EventQueue.access0(Unknown Source) at
java.awt.EventQueue.run(Unknown Source) at
java.awt.EventQueue.run(Unknown Source) at
java.security.AccessController.doPrivileged(Native Method) at
java.security.ProtectionDomain.doIntersectionPrivilege(Unknown
Source) at
java.security.ProtectionDomain.doIntersectionPrivilege(Unknown
Source) at java.awt.EventQueue.run(Unknown Source) at
java.awt.EventQueue.run(Unknown Source) at
java.security.AccessController.doPrivileged(Native Method) at
java.security.ProtectionDomain.doIntersectionPrivilege(Unknown
Source) at java.awt.EventQueue.dispatchEvent(Unknown Source) at
java.awt.EventDispatchThread.pumpOneEventForFilters(Unknown Source)
at java.awt.EventDispatchThread.pumpEventsForFilter(Unknown Source)
at java.awt.EventDispatchThread.pumpEventsForHierarchy(Unknown
Source) at java.awt.EventDispatchThread.pumpEvents(Unknown Source)
at java.awt.EventDispatchThread.pumpEvents(Unknown Source) at
java.awt.EventDispatchThread.run(Unknown Source)
org.eclipse.jdi.TimeoutException: Timeout occurred while waiting for
packet 142. at
org.eclipse.jdi.internal.connect.PacketReceiveManager.getReply(PacketReceiveManager.java:186)
at
org.eclipse.jdi.internal.connect.PacketReceiveManager.getReply(PacketReceiveManager.java:197)
at org.eclipse.jdi.internal.MirrorImpl.requestVM(MirrorImpl.java:191)
at org.eclipse.jdi.internal.MirrorImpl.requestVM(MirrorImpl.java:226)
at
org.eclipse.jdi.internal.VirtualMachineImpl.exit(VirtualMachineImpl.java:716)
at processing.mode.java.runner.Runner.close(Runner.java:961) at
processing.mode.java.JavaEditor.handleStop(JavaEditor.java:728) at
processing.mode.java.JavaToolbar.handlePressed(JavaToolbar.java:96)
at processing.app.EditorToolbar.mousePressed(EditorToolbar.java:474)
at java.awt.Component.processMouseEvent(Unknown Source) at
javax.swing.JComponent.processMouseEvent(Unknown Source) at
java.awt.Component.processEvent(Unknown Source) at
java.awt.Container.processEvent(Unknown Source) at
java.awt.Component.dispatchEventImpl(Unknown Source) at
java.awt.Container.dispatchEventImpl(Unknown Source) at
java.awt.Component.dispatchEvent(Unknown Source) at
java.awt.LightweightDispatcher.retargetMouseEvent(Unknown Source) at
java.awt.LightweightDispatcher.processMouseEvent(Unknown Source) at
java.awt.LightweightDispatcher.dispatchEvent(Unknown Source) at
java.awt.Container.dispatchEventImpl(Unknown Source) at
java.awt.Window.dispatchEventImpl(Unknown Source) at
java.awt.Component.dispatchEvent(Unknown Source) at
java.awt.EventQueue.dispatchEventImpl(Unknown Source) at
java.awt.EventQueue.access0(Unknown Source) at
java.awt.EventQueue.run(Unknown Source) at
java.awt.EventQueue.run(Unknown Source) at
java.security.AccessController.doPrivileged(Native Method) at
java.security.ProtectionDomain.doIntersectionPrivilege(Unknown
Source) at
java.security.ProtectionDomain.doIntersectionPrivilege(Unknown
Source) at java.awt.EventQueue.run(Unknown Source) at
java.awt.EventQueue.run(Unknown Source) at
java.security.AccessController.doPrivileged(Native Method) at
java.security.ProtectionDomain.doIntersectionPrivilege(Unknown
Source) at java.awt.EventQueue.dispatchEvent(Unknown Source) at
java.awt.EventDispatchThread.pumpOneEventForFilters(Unknown Source)
at java.awt.EventDispatchThread.pumpEventsForFilter(Unknown Source)
at java.awt.EventDispatchThread.pumpEventsForHierarchy(Unknown
Source) at java.awt.EventDispatchThread.pumpEvents(Unknown Source)
at java.awt.EventDispatchThread.pumpEvents(Unknown Source) at
java.awt.EventDispatchThread.run(Unknown Source)
您可能在收到 Whosebug 异常之前达到了递归调用的最大数量。我建议在 Java 控制面板中更改堆 space 大小。
- Go to the Control Panel in Windows.
- Click on Java.
- Go to the Java tab and click on View.
- You will see a section called Runtime Parameters. Double click on that column (make sure you double click on the version you are
currently using). This will allow you to edit it.
There are a few ways to set your heap size. I will list them:
-Xms<size> set initial Java heap size
-Xmx<size> set maximum Java heap size
-Xss<size> set java thread stack size
As an example, I have set mine to: -Xms512m. Don't forget to Apply/Save the changes made.
对于Eclipse,还可以设置堆space:
- In Run->Run Configuration find the Name of the class you have been
running, select it, click the Arguments tab then add: -Xms512M -Xmx1524M to the VM Arguments section
递归时可能会超出堆栈。你的树不应该太深。看到一些考虑 .
但是,根据您提供的堆栈跟踪和代码,问题不在这部分代码中。根据堆栈跟踪,看起来您递归调用了一些 GUI 方法或鼠标事件处理方法,而不是 pintar() 方法。
它可能只是速度慢。从 100 x 100 图像变为 500 x 500 图像会将像素数从 10,000 增加到 250,000。这是一个很大的飞跃。而且您的递归方法最终将对每个像素进行多次调用。这可能会使事情陷入困境。
要查看是否是这种情况,请尝试逐渐增加图像大小,并在图像大小增加时计算程序所需的时间。您可以预计 500x500 版本所花的时间是 100x100 版本的 25 倍。这对你来说是合理的执行时间吗?
如果是这样的性能问题,请查看是否可以将其切换为迭代实现,并可能将 stroke()
调用提升到循环之外。
还要注意 draw()
是在循环内调用的,除非你用 noLoop()
和 redraw()
控制它。你可能想在这里做。您的 draw()
在较大的图像上可能足够慢,以至于它不能 运行 在其分配的时间片内,并且 draw()
调用和事件处理正在得到备份。
您的错误确实是由过多的递归引起的 Whosebug,但处理过程中会用您看到的奇怪错误来弥补这一点。关于该错误的文档是 here.
您可以增加 Java 堆栈大小以增加递归调用的限制。可以找到信息 here,但要点是您必须在 运行 时将 -Xss 设置传递到 Java。
但是,该设置要求您 运行 您的草图作为 Java 应用程序。这是可能的,但它涉及将草图导出为 jar,然后 运行 通过命令提示符打开 jar,或切换到 eclipse。这比简单地点击 Processing 中的 运行 按钮要多得多 - 而且您发送 jar 的任何用户都必须做同样的事情。
相反,您可能应该重构您的算法以消除过多的递归。
我是运行在处理递归方法,但是当作业太大的时候,报错:
crashed in event thread due to Timeout occurred while waiting for packet 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);
}
}
}
回溯:
crashed in event thread due to Timeout occurred while waiting for packet 139. org.eclipse.jdi.TimeoutException: Timeout occurred while waiting for packet 139. at org.eclipse.jdi.internal.connect.PacketReceiveManager.getReply(PacketReceiveManager.java:186) at org.eclipse.jdi.internal.connect.PacketReceiveManager.getReply(PacketReceiveManager.java:197) at org.eclipse.jdi.internal.MirrorImpl.requestVM(MirrorImpl.java:191) at org.eclipse.jdi.internal.MirrorImpl.requestVM(MirrorImpl.java:226) at org.eclipse.jdi.internal.ThreadReferenceImpl.frames(ThreadReferenceImpl.java:257) at org.eclipse.jdi.internal.ThreadReferenceImpl.frames(ThreadReferenceImpl.java:240) at processing.mode.java.runner.Runner.findException(Runner.java:888) at 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.run(Runner.java:688) org.eclipse.jdi.TimeoutException: Timeout occurred while waiting for packet 140. at org.eclipse.jdi.internal.connect.PacketReceiveManager.getReply(PacketReceiveManager.java:186) at org.eclipse.jdi.internal.connect.PacketReceiveManager.getReply(PacketReceiveManager.java:197) at org.eclipse.jdi.internal.MirrorImpl.requestVM(MirrorImpl.java:191) at org.eclipse.jdi.internal.MirrorImpl.requestVM(MirrorImpl.java:226) at org.eclipse.jdi.internal.VirtualMachineImpl.exit(VirtualMachineImpl.java:716) at processing.mode.java.runner.Runner.close(Runner.java:961) at processing.mode.java.JavaEditor.handleStop(JavaEditor.java:728) at processing.mode.java.JavaToolbar.handlePressed(JavaToolbar.java:96) at processing.app.EditorToolbar.mousePressed(EditorToolbar.java:474) at java.awt.Component.processMouseEvent(Unknown Source) at javax.swing.JComponent.processMouseEvent(Unknown Source) at java.awt.Component.processEvent(Unknown Source) at java.awt.Container.processEvent(Unknown Source) at java.awt.Component.dispatchEventImpl(Unknown Source) at java.awt.Container.dispatchEventImpl(Unknown Source) at java.awt.Component.dispatchEvent(Unknown Source) at java.awt.LightweightDispatcher.retargetMouseEvent(Unknown Source) at java.awt.LightweightDispatcher.processMouseEvent(Unknown Source) at java.awt.LightweightDispatcher.dispatchEvent(Unknown Source) at java.awt.Container.dispatchEventImpl(Unknown Source) at java.awt.Window.dispatchEventImpl(Unknown Source) at java.awt.Component.dispatchEvent(Unknown Source) at java.awt.EventQueue.dispatchEventImpl(Unknown Source) at java.awt.EventQueue.access0(Unknown Source) at java.awt.EventQueue.run(Unknown Source) at java.awt.EventQueue.run(Unknown Source) at java.security.AccessController.doPrivileged(Native Method) at java.security.ProtectionDomain.doIntersectionPrivilege(Unknown Source) at java.security.ProtectionDomain.doIntersectionPrivilege(Unknown Source) at java.awt.EventQueue.run(Unknown Source) at java.awt.EventQueue.run(Unknown Source) at java.security.AccessController.doPrivileged(Native Method) at java.security.ProtectionDomain.doIntersectionPrivilege(Unknown Source) at java.awt.EventQueue.dispatchEvent(Unknown Source) at java.awt.EventDispatchThread.pumpOneEventForFilters(Unknown Source) at java.awt.EventDispatchThread.pumpEventsForFilter(Unknown Source) at java.awt.EventDispatchThread.pumpEventsForHierarchy(Unknown Source) at java.awt.EventDispatchThread.pumpEvents(Unknown Source) at java.awt.EventDispatchThread.pumpEvents(Unknown Source) at java.awt.EventDispatchThread.run(Unknown Source) org.eclipse.jdi.TimeoutException: Timeout occurred while waiting for packet 141. at org.eclipse.jdi.internal.connect.PacketReceiveManager.getReply(PacketReceiveManager.java:186) at org.eclipse.jdi.internal.connect.PacketReceiveManager.getReply(PacketReceiveManager.java:197) at org.eclipse.jdi.internal.MirrorImpl.requestVM(MirrorImpl.java:191) at org.eclipse.jdi.internal.MirrorImpl.requestVM(MirrorImpl.java:226) at org.eclipse.jdi.internal.VirtualMachineImpl.exit(VirtualMachineImpl.java:716) at processing.mode.java.runner.Runner.close(Runner.java:961) at processing.mode.java.JavaEditor.handleStop(JavaEditor.java:728) at processing.mode.java.JavaToolbar.handlePressed(JavaToolbar.java:96) at processing.app.EditorToolbar.mousePressed(EditorToolbar.java:474) at java.awt.Component.processMouseEvent(Unknown Source) at javax.swing.JComponent.processMouseEvent(Unknown Source) at java.awt.Component.processEvent(Unknown Source) at java.awt.Container.processEvent(Unknown Source) at java.awt.Component.dispatchEventImpl(Unknown Source) at java.awt.Container.dispatchEventImpl(Unknown Source) at java.awt.Component.dispatchEvent(Unknown Source) at java.awt.LightweightDispatcher.retargetMouseEvent(Unknown Source) at java.awt.LightweightDispatcher.processMouseEvent(Unknown Source) at java.awt.LightweightDispatcher.dispatchEvent(Unknown Source) at java.awt.Container.dispatchEventImpl(Unknown Source) at java.awt.Window.dispatchEventImpl(Unknown Source) at java.awt.Component.dispatchEvent(Unknown Source) at java.awt.EventQueue.dispatchEventImpl(Unknown Source) at java.awt.EventQueue.access0(Unknown Source) at java.awt.EventQueue.run(Unknown Source) at java.awt.EventQueue.run(Unknown Source) at java.security.AccessController.doPrivileged(Native Method) at java.security.ProtectionDomain.doIntersectionPrivilege(Unknown Source) at java.security.ProtectionDomain.doIntersectionPrivilege(Unknown Source) at java.awt.EventQueue.run(Unknown Source) at java.awt.EventQueue.run(Unknown Source) at java.security.AccessController.doPrivileged(Native Method) at java.security.ProtectionDomain.doIntersectionPrivilege(Unknown Source) at java.awt.EventQueue.dispatchEvent(Unknown Source) at java.awt.EventDispatchThread.pumpOneEventForFilters(Unknown Source) at java.awt.EventDispatchThread.pumpEventsForFilter(Unknown Source) at java.awt.EventDispatchThread.pumpEventsForHierarchy(Unknown Source) at java.awt.EventDispatchThread.pumpEvents(Unknown Source) at java.awt.EventDispatchThread.pumpEvents(Unknown Source) at java.awt.EventDispatchThread.run(Unknown Source) org.eclipse.jdi.TimeoutException: Timeout occurred while waiting for packet 142. at org.eclipse.jdi.internal.connect.PacketReceiveManager.getReply(PacketReceiveManager.java:186) at org.eclipse.jdi.internal.connect.PacketReceiveManager.getReply(PacketReceiveManager.java:197) at org.eclipse.jdi.internal.MirrorImpl.requestVM(MirrorImpl.java:191) at org.eclipse.jdi.internal.MirrorImpl.requestVM(MirrorImpl.java:226) at org.eclipse.jdi.internal.VirtualMachineImpl.exit(VirtualMachineImpl.java:716) at processing.mode.java.runner.Runner.close(Runner.java:961) at processing.mode.java.JavaEditor.handleStop(JavaEditor.java:728) at processing.mode.java.JavaToolbar.handlePressed(JavaToolbar.java:96) at processing.app.EditorToolbar.mousePressed(EditorToolbar.java:474) at java.awt.Component.processMouseEvent(Unknown Source) at javax.swing.JComponent.processMouseEvent(Unknown Source) at java.awt.Component.processEvent(Unknown Source) at java.awt.Container.processEvent(Unknown Source) at java.awt.Component.dispatchEventImpl(Unknown Source) at java.awt.Container.dispatchEventImpl(Unknown Source) at java.awt.Component.dispatchEvent(Unknown Source) at java.awt.LightweightDispatcher.retargetMouseEvent(Unknown Source) at java.awt.LightweightDispatcher.processMouseEvent(Unknown Source) at java.awt.LightweightDispatcher.dispatchEvent(Unknown Source) at java.awt.Container.dispatchEventImpl(Unknown Source) at java.awt.Window.dispatchEventImpl(Unknown Source) at java.awt.Component.dispatchEvent(Unknown Source) at java.awt.EventQueue.dispatchEventImpl(Unknown Source) at java.awt.EventQueue.access0(Unknown Source) at java.awt.EventQueue.run(Unknown Source) at java.awt.EventQueue.run(Unknown Source) at java.security.AccessController.doPrivileged(Native Method) at java.security.ProtectionDomain.doIntersectionPrivilege(Unknown Source) at java.security.ProtectionDomain.doIntersectionPrivilege(Unknown Source) at java.awt.EventQueue.run(Unknown Source) at java.awt.EventQueue.run(Unknown Source) at java.security.AccessController.doPrivileged(Native Method) at java.security.ProtectionDomain.doIntersectionPrivilege(Unknown Source) at java.awt.EventQueue.dispatchEvent(Unknown Source) at java.awt.EventDispatchThread.pumpOneEventForFilters(Unknown Source) at java.awt.EventDispatchThread.pumpEventsForFilter(Unknown Source) at java.awt.EventDispatchThread.pumpEventsForHierarchy(Unknown Source) at java.awt.EventDispatchThread.pumpEvents(Unknown Source) at java.awt.EventDispatchThread.pumpEvents(Unknown Source) at java.awt.EventDispatchThread.run(Unknown Source)
您可能在收到 Whosebug 异常之前达到了递归调用的最大数量。我建议在 Java 控制面板中更改堆 space 大小。
- Go to the Control Panel in Windows.
- Click on Java.
- Go to the Java tab and click on View.
- You will see a section called Runtime Parameters. Double click on that column (make sure you double click on the version you are currently using). This will allow you to edit it.
There are a few ways to set your heap size. I will list them:
-Xms<size> set initial Java heap size -Xmx<size> set maximum Java heap size -Xss<size> set java thread stack size
As an example, I have set mine to: -Xms512m. Don't forget to Apply/Save the changes made.
对于Eclipse,还可以设置堆space:
- In Run->Run Configuration find the Name of the class you have been running, select it, click the Arguments tab then add: -Xms512M -Xmx1524M to the VM Arguments section
递归时可能会超出堆栈。你的树不应该太深。看到一些考虑
但是,根据您提供的堆栈跟踪和代码,问题不在这部分代码中。根据堆栈跟踪,看起来您递归调用了一些 GUI 方法或鼠标事件处理方法,而不是 pintar() 方法。
它可能只是速度慢。从 100 x 100 图像变为 500 x 500 图像会将像素数从 10,000 增加到 250,000。这是一个很大的飞跃。而且您的递归方法最终将对每个像素进行多次调用。这可能会使事情陷入困境。
要查看是否是这种情况,请尝试逐渐增加图像大小,并在图像大小增加时计算程序所需的时间。您可以预计 500x500 版本所花的时间是 100x100 版本的 25 倍。这对你来说是合理的执行时间吗?
如果是这样的性能问题,请查看是否可以将其切换为迭代实现,并可能将 stroke()
调用提升到循环之外。
还要注意 draw()
是在循环内调用的,除非你用 noLoop()
和 redraw()
控制它。你可能想在这里做。您的 draw()
在较大的图像上可能足够慢,以至于它不能 运行 在其分配的时间片内,并且 draw()
调用和事件处理正在得到备份。
您的错误确实是由过多的递归引起的 Whosebug,但处理过程中会用您看到的奇怪错误来弥补这一点。关于该错误的文档是 here.
您可以增加 Java 堆栈大小以增加递归调用的限制。可以找到信息 here,但要点是您必须在 运行 时将 -Xss 设置传递到 Java。
但是,该设置要求您 运行 您的草图作为 Java 应用程序。这是可能的,但它涉及将草图导出为 jar,然后 运行 通过命令提示符打开 jar,或切换到 eclipse。这比简单地点击 Processing 中的 运行 按钮要多得多 - 而且您发送 jar 的任何用户都必须做同样的事情。
相反,您可能应该重构您的算法以消除过多的递归。