some java questions...

A

alessandro

Hi, in my third java program (yes, I'm new to this lang.) I have some
troubles:
-I often get StackOverFlow exceptions. What are the common problems that
lead to this error? I come from C/C++ programming, and perhaps have some
habits that are wrong used with Java...
-My program connects with two other instances of itself trought sockets.
Managing the connections requires the creation of 5 threads: one for the
connection (but I close the thread just after) and four for the 2 I/O
channels. I asked around and many people said this is the only available way
for non-blocking I/O (without using NIO). But my program is toooo slow now.
It requires 5 seconds for the connection (with all three program running on
the same machine) and several seconds even for reading -writing less than 10
bytes. Is a thread issue? Or am I making some stupid error?
 
M

Michael Borgwardt

alessandro said:
Hi, in my third java program (yes, I'm new to this lang.) I have some
troubles:
-I often get StackOverFlow exceptions. What are the common problems that
lead to this error?

There's really only one thing that can result in a stack overflow:
badly applied recursion. Recursion should really only be used in
algorithms that inherently put tight limits on the recursion depths,
e.g. in sorting algorithms it's usually the logarithm of the number
of elements.
I come from C/C++ programming, and perhaps have some
habits that are wrong used with Java...

Excessive recursion is wrong in C as well, even though it might fail
lass often due to larger stack sizes.

-My program connects with two other instances of itself trought sockets.
Managing the connections requires the creation of 5 threads: one for the
connection (but I close the thread just after) and four for the 2 I/O
channels. I asked around and many people said this is the only available way
for non-blocking I/O (without using NIO). But my program is toooo slow now.
It requires 5 seconds for the connection (with all three program running on
the same machine) and several seconds even for reading -writing less than 10
bytes. Is a thread issue? Or am I making some stupid error?

Quite definitely the latter.
 
A

alessandro

There's really only one thing that can result in a stack overflow:
badly applied recursion. Recursion should really only be used in
algorithms that inherently put tight limits on the recursion depths,
e.g. in sorting algorithms it's usually the logarithm of the number
of elements.

Yes: I use recursion in order to build a Min-Max Tree... As far as I know,
using recursion is the traditional method to do this, so I don't know how to
avoid Stack Overflow. I there a command to specify the stack size?

And for my second problem... what are the common mistakes that can result in
a slow I/O?

Thank you for the reply
Best regards,
Alessandro
 
P

Paul Lutus

alessandro said:
Yes: I use recursion in order to build a Min-Max Tree... As far as I know,
using recursion is the traditional method to do this, so I don't know how
to avoid Stack Overflow.

That's easy. Understand how your code works, so you will know how deep the
recursion will go in the worst case.
I there a command to specify the stack size?

Maybe it would be better to solve the problem at the source.
And for my second problem... what are the common mistakes that can result
in a slow I/O?

Not posting your code?
 
C

Chris Uppal

alessandro said:
Yes: I use recursion in order to build a Min-Max Tree... As far as I know,
using recursion is the traditional method to do this, so I don't know how
to avoid Stack Overflow.

The obvious possibilities are that there's a bug in your code or that you are
hitting a pathological case for the algorithm you are using. In either case
the thing to do is study /exactly/ what your code is doing (difficult, I know,
because it's hard to see effects that you don't expect).

I there a command to specify the stack size?

Yes and no. Any /specific/ implementation may, or may not, have (or even need)
such options. In fact the JVMs from Sun do have an option to control stack
size, but I can't offhand remember what it is. (And, even if I could, I would
be unlikely to mention it here because I'm convinced that your real problem is
not the configured stack size of the JVM you are using)

And for my second problem... what are the common mistakes that can result
in a slow I/O?

The most common is a failure to understand how and where to use buffering.
However, bad buffering wouldn't even come /close/ to explaining the
extraordinary slowness that you are seeing, so I don't believe that is the
problem. I'm afraid that I can't suggest what might be the real problem
without more information.

-- chris
 
A

anon

alessandro said:
Hi, in my third java program (yes, I'm new to this lang.) I have some
troubles:
-I often get StackOverFlow exceptions. What are the common problems that
lead to this error? I come from C/C++ programming, and perhaps have some
habits that are wrong used with Java...
-My program connects with two other instances of itself trought sockets.
Managing the connections requires the creation of 5 threads: one for the
connection (but I close the thread just after) and four for the 2 I/O
channels. I asked around and many people said this is the only available way
for non-blocking I/O (without using NIO). But my program is toooo slow now.
It requires 5 seconds for the connection (with all three program running on
the same machine) and several seconds even for reading -writing less than 10
bytes. Is a thread issue? Or am I making some stupid error?
Some others have already given tips on your stack overflow problems, so
I'll just add that you may want to look into using the
java.io.PipedInputStream, java.io.PipedOutputStream,
java.io.PipedReader, and java.io.PipedWriter streams for your
interthread communications instead of java.net.Socket.
 
G

Guest

Hi, in my third java program (yes, I'm new to this lang.)

You may want to hang out in comp.lang.help while you get the basics of the
language down.

The others have given good advice as far as your current problems.

La'ie Techie
 
G

Gordon Beaton

Some others have already given tips on your stack overflow problems,
so I'll just add that you may want to look into using the
java.io.PipedInputStream, java.io.PipedOutputStream,
java.io.PipedReader, and java.io.PipedWriter streams for your
interthread communications instead of java.net.Socket.

Or even better: a queue of object references. Why serialize when it isn't
necessary?

/gordon
 
A

alessandro

Thank you all for your help. I solved the second problem, an it was very
stupid: the program executed a loop that did nothing more than checking if
the connection was ready or data were available: this way the program burned
99% of the resources of the system doing nothing. A timer based approach
will work better, I think.

Fo the first problem...well, my tree reaches a depth of 4, creating some
hundred of thousand of nodes, (each node creates up to 30 children, but in
most cases these are less.
 
C

Chris Uppal

alessandro said:
Fo the first problem...well, my tree reaches a depth of 4, creating some
hundred of thousand of nodes, (each node creates up to 30 children, but in
most cases these are less.

The first thing I'd check is that you are using recursion /only/ when you go
down a level in the tree, and that you are using normal iteration (a "for" or
"while" loop) to loop over the children. If you have coded it that way then
the maximum depth of recursion is the same as the max depth of your tree --
i.e. 4 -- and there is no problem at all using small depths like that.

-- chris
 
M

Michael Borgwardt

alessandro said:
Thank you all for your help. I solved the second problem, an it was very
stupid: the program executed a loop that did nothing more than checking if
the connection was ready or data were available: this way the program burned
99% of the resources of the system doing nothing. A timer based approach
will work better, I think.

Even that would be really bad code. Use blocking IO and wait()/notify()
Fo the first problem...well, my tree reaches a depth of 4, creating some
hundred of thousand of nodes, (each node creates up to 30 children, but in
most cases these are less.

A well-written algorithm that manipulates such a tree should not
cause a stack overflow.
 
A

alessandro

Here the code. From your answers, it seems that a tree of 100000+ nodes
should fit in the stack. The following code generates the tree. Each time I
call it, it generates the tree. After a dozen of calls, it throws a
StackOverflow exception. Where's the bug? (note: it's a Alpha-beta tree).

public String Generate(Board b, Board oldb)
{
...
Max(b, oldb, -10000, 10000, tree_depth);
...
}

protected int Max(Board b, Board oldb, int alpha, int beta, int depth)
{
int tmp = b.CheckForVictory(); //Controlliamo che non sia il termine
della partita
if(tmp == 1) return 10000;
else if(tmp == 2) return -10000;

if(depth == 0) return EvaluateGame(b, oldb); // Se abbiamo raggiunto la
profondità massima, adottiamo l'euristica

//Nessuna vittoria
Board children[][] = new Board[6][5];
for(int x = 0; x < 6; x++)
for(int y = 0; y < 5; y++)
{
if(!b.Verify(x, y, true)) continue; //La mossa non è valida

children[x][y] = new Board(b);
children[x][y].AddFast(x, y, true);

tmp = Min(children[x][y], b, alpha, beta, depth-1);
if(tmp > alpha)
{
alpha = tmp;
_x = x;
_y = y;
}
if(beta <= alpha) return beta;
}
return alpha;
}

protected int Min(Board b, Board oldb, int alpha, int beta, int depth)
{
int tmp = b.CheckForVictory(); //Controlliamo che non sia il termine
della partita
if(tmp == 1) return -10000;
else if(tmp == 2) return 10000;

if(depth == 0) return -EvaluateGame(b, oldb); // Se abbiamo raggiunto la
profondità massima, adottiamo l'euristica

//Nessuna vittoria
Board children[][] = new Board[6][5];
for(int x = 0; x < 6; x++)
for(int y = 0; y < 5; y++)
{
if(!b.Verify(x, y, false)) continue; //La mossa non è valida

children[x][y] = new Board(b);
children[x][y].AddFast(x, y, false);

tmp = Max(children[x][y], b, alpha, beta, depth-1);
if(tmp < beta)
{
beta = tmp;
_x = x;
_y = y;
}
if(beta <= alpha) return alpha;
}
return beta;
}
 
M

Michael Borgwardt

alessandro said:
Here the code. From your answers, it seems that a tree of 100000+ nodes
should fit in the stack. The following code generates the tree. Each time I
call it, it generates the tree. After a dozen of calls, it throws a
StackOverflow exception. Where's the bug? (note: it's a Alpha-beta tree).

I don't have the time to do a complete analyzation of the algorithm.
At first glance, it looks OK. Min and Max (which, as Java methods,
should not begin with an uppercase letter) call each other, but
with depth reduced by one.

So the problem must be one of the following:

- A problem with one of the methods you didn't post, CheckForVictory()
and EvluateGame(). Do they call each other, Min() or Max()?

- An error in the algorithm so that the depth parameter does not reflect the
actual depth of the tree, i.e. incorrect termination conditions.

- For some reson the tree degenerates and so its depth is much greater than
you think.

To find out which of these applies, a stacktrace of the StackoverflowError
might help, as migh a debug output at the beginning of each method showing
with which parameters it was called.
 
P

Paul Lutus

alessandro said:
Here the code. From your answers, it seems that a tree of 100000+ nodes
should fit in the stack.

Why not add a stack depth register and monitor it? This will reveal any
situation that exceeds a reasonable depth, and you could even stack trace
on reaching an unacceptable depth.
 

Ask a Question

Want to reply to this thread or ask your own question?

You'll need to choose a username for the site, which only take a couple of moments. After that, you can post your question and our members will help you out.

Ask a Question

Members online

No members online now.

Forum statistics

Threads
473,744
Messages
2,569,482
Members
44,901
Latest member
Noble71S45

Latest Threads

Top