Decrease max stacksize at runtime in Java - java

I'm attempting to write a junit test to guard against a piece of code getting stuck in a endless iteration which will eventually cause a StackOverflow.
so i'm looking for a way to decrease the stack size at runtime so the Junittest will fail faster.
setting the max stack as a jvm argument is not possible because the test is part of a much larger test suite.

You could run a recursive method which will run itself a given number of times and then execute a given action. Sounds pretty flaky though :(
Something like:
public void eatStackThenExecute(int depth, Runnable action)
{
// Maybe put some locals here (and use them) to eat more stack per iteration?
if (depth == 0)
{
action();
}
else
{
eatStackThenExecute(depth - 1, action);
}
}
EDIT: It's possible that smart JVMs will optimise the tail call here, so it may be that we'd need to do "something" after the recursive call to stop that from happening...
Ick 'n stuff :(

It's not possible to set the stack size at runtime, but perhaps you can:
invoke that piece of code inside a different thread - retaining the reference to it;
periodically poll thread.getStackTrace() and fail if its size is larger than x;
cancel the check if execution terminates correctly.
not-compiled proof of concept code ( does not properly check all edge conditions ):
AtomicBoolean success = new AtomicBoolean(false);
Thread t= new Thread(new Runnable() {
public void run() {
codeToTest();
success.set(true);
}
});
t.start();
while ( t.isAlive() ) {
if ( t.getStackTrace().length > 50 )
fail("Stack trace too large");
Thread.sleep(50);
}
assertTrue(sucess.get());

You can only set parameters like this at startup, however you can start another process from Java. So you could make your unit tests start a second process with a smaller stack size to perform your test.

This gets a bit... well, interesting... but it might be worth it.
Take your .class file and decompile it with jasper.
Edit the resulting JVM assembly-esque code and add or alter the ".limit stack x" argument for the routine you want to test in this manner.
Recompile with Jasmin.
Run it and test.

Related

Is there any way to find the execution flow of java code?

public class Threads1 {
int x = 0;
public class Runner implements Runnable {
public void run(){
int current = 0;
for(int i = 0; i<4; i++){
current = x;
System.out.println(current + ", ");
x = current + 2;
}
}
}
public static void main(String[] args) {
new Threads1().go();
}
public void go(){
Runnable r1 = new Runner();
new Thread(r1).start();
new Thread(r1).start();
}
}
I want to find the execution step of this code ,Is there any way that can show me the execution flow in my consol?
Print Statements
Put System.out.println() statements in appropriate places in your code. For example, put
System.out.println("Entering a for loop");
before a for loop to know when the for loop is entered.
Debugger
Find out how to set a breakpoint in your IDE. Set a breakpoint at start of the portion of code that you don't understand. When that line is going to be executed, the program will pause and allow you to examine the values in variables, the stack trace, the threads, etc. You can also find out which thread is the current line running on in the debugger.
Additionally, find "Step in", "Step over" and "Step out" buttons on the debugger. These will allow you to "step through" your code line by line, so as to allow you to see the path that execution takes.
Java Threads
If you have several threads running at once ther is no way to predict which one of them finishes first or when something is done, like to differen programms. Different threads are executed by different cores of you CPU and therefore completely independend from oneanother, this affects computation speed and order (branchprediction in you CPU plays one role here). This can lead to pretty difficult bugs to find because they only happen sometimes.
Your Problem
The execution order of the threads is not determend a compile time it's decided by you CPU at runtime and is not consistent because the threads do not know they have a partner.
Solution
To display the order at which it happend just insert System.out.println statements in your methodes and create so a sort of log what happened in you console.
Controled Threads with Synchronized
If you use threads, Java supports the synchronized keyword. Synchronized allows you to get a bit of control over several threads. For example only one thread at a time can interact with a variable or methode. For more information just google Java synchronized threads.
One of the possibilities is to create a field in the class that would differentiate both threads to make you sure which thread prints the values to the console in the moment (you should contain this additional value in the informations you print to the console in the "for" loop to know if the first or the second thread has performed activity printed to the console).
Another possibility is using debugger.

Wait for method to Finish, and weird interaction with System.println

I am trying to write a genetic program to play through a game, but I am running into a bit of a snag. When I call this code:
public double playMap (GameBoard gb, Player p) {
gb.playerController = p;
Game g = new Game(gb);
int initHP = 0;
for (Unit u : gb.enemy.units) {
initHP += u.maxHP;
}
g.playGame(false);
int finalHP = 0;
for (Unit u : gb.enemy.units) {
finalHP += u.currHP;
}
System.out.println(" " + initHP);
System.out.println(" " + finalHP);
System.out.println(" " + (finalHP - initHP));
if (initHP == finalHP) {
return -10;
}
return initHP - finalHP;
}
the g.playGame() line does not have time to finish, and I am getting incorrect results from the function. I can wait out unit the game is over with a
while (!g.isDone) {
System.out.println(g.isDone);
}
but not with the same while loop without a print statement. I know there has to be a more elegant solution, and I cant seem to implement the methods I have seen. Also if anyone knows why I need the print statement in the while loop to get it to wait that would be great too.
Thanks in advance.
ADDED playGame:
public void playGame(boolean visual) {
Global.visual = visual;
if (Global.visual) {
JFrame application = new JFrame();
application.setBackground(Color.DARK_GRAY);
application.setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);
application.add(this);
application.setSize(500, 400); // window is 500 pixels wide, 400 high
application.setVisible(true);
}
PlayerInput pi = new PlayerInput();
this.addKeyListener(pi);
final Timer timer = new Timer(10/60, null);
ActionListener listener = new ActionListener() {
#Override
public void actionPerformed(ActionEvent e) {
pi.addPressed();
if (update(pi)) {
// application.setVisible(false);
// application.dispose();
System.out.println(gb.toString());
isDone = true;
timer.stop();
}
pi.reset();
}
};
timer.addActionListener(listener);
timer.start();
while (!isDone) {
System.out.println(isDone);
}
}
First of all, this is a really bad way of doing this. This approach is called "busy waiting" and it is very inefficient.
The problem is most likely that reads and writes to g.isDone are not properly synchronized. As a consequence, there are no guarantees that the "waiting" thread will ever see the update to g.isDone that sets it to true.
There are various ways to ensure that the update is seen. The simplest one is to declare isDone as volatile. Another one is to do the reads and writes within a primitive lock.
The reason that the println() call "fixes" things is that println is doing some synchronization behind the scenes, and this is leading to serendipitous cache flushing (or something) that makes your update visible. (In other words: you got lucky, but exactly how you got lucky is hard to tie down.)
A better solution is to use another mechanism for coordinating the two threads.
You could use Thread.join() so that one thread waits for the other one to terminate (completely!).
You could use a Latch or Semaphore or similar to implement the waiting.
You could use an Executor that delivers a Future and then call Future.get() to wait for that to deliver its result.
You could even use Object.wait and Object.notify ... though that is low-level and easy to get wrong.
Without seeing the full context, it is hard to judge which approach would be most appropriate. But they would all be better than busy-waiting.
Another answer says this:
If you remove the System.out.println() call from your loop, I believe that the compiler simply doesn't include the loop in the Java bytecode, believing it to be superfluous.
As I explained above, the real problem is inadequate synchronization. To be technical, there needs to be a happens-before relationship between the write of isDone in one thread and the read of isDone in the other one. Various things will give that ... but without that, the compiler is entitled to assume that:
the writing thread does not need to flush the write to memory
the reading thread does not need to check that the memory has changed.
For example, without the happens-before, the compiler would be permitted to optimize
while (!g.isDone) {
// do nothing
}
to
if (!g.isDone) {
// do nothing
}
We don't know if this actually happens, or whether the actual cause of "non-visibility" of the update to isDone is something else. (Indeed, it could be JVM version / platform specific. To be sure, you would need to get the JIT compiler to dump the native code for the methods, and analyze the code very carefully.)
Apparently you are running your game in a separate thread. Assuming that thread is called foo, calling foo.join() will block the calling thread until foo finishes executing. You can simply replace your entire loop with foo.join().
If you remove the System.out.println() call from your loop, I believe that the compiler simply doesn't include the loop in the Java bytecode, believing it to be superfluous.

Why won't this 'if' statement run in a while loop without something else also happening in the while loop?

I'm having a problem where an if statement is only running if there is something else happening before it in the while loop.
Here is the code I want to use:
public void load() throws IOException, InterruptedException {
while (true) {
if (findGame == true) {
System.out.println(findGame);
}
}
}
That is simplified but it shows my problem. Basically, when findGame == true, the if statement does not run. The reason I don't think the if statement is running is because the variable is not being printed out to the console.
I did some tests and found that the if statement ran with the following code:
public void load() throws IOException, InterruptedException {
while (true) {
System.out.println("foo"); // New code added
if (findGame == true) {
System.out.println(findGame);
}
}
}
My question is why does it work with the above code but not the first one? The only difference between the two is that the one that works has something else added to the while loop.
If it makes a difference, the code I've shown above is running in a separate thread.
If it makes a difference, the code I've shown above is running in a separate thread.
And that's the problem. You're relying on a value set by one thread to be visible in another - and there's no such guarantee without memory barriers being involved. In your second code, the call to println is almost certainly responsible for creating the memory barriers required for the reading thread to "see" the value written by the writing thread. Memory models are hard, unfortunately :(
If you use AtomicBoolean instead of just a boolean field, you may well find the first code works instead - but even so, a tight loop is generally a bad idea. It would be better to use a semaphore or some similar kind of signalling, so the "reading" thread could just wait (idly) until there's a change. Look into java.util.concurrent for classes such as Semaphore and CountDownLatch. (You can do it with just wait and notify, but it'll be simpler if you use higher-level abstractions.)

Why using "volatile" does not show any difference here?

I am learning the usage of volatile in Java. Here is a sample code I read from many articles:
static volatile boolean shutdownRequested = false;
...
public void shutdown() { shutdownRequested = true; }
public void doWork() {
while (!shutdownRequested) {
// do stuff
}
}
I try this on my machine with and without "volatile", but they show no difference: they can both shutdown.
So what's wrong? Is there anything wrong with my code, or does it depend on the version of the Java compiler?
Addition: in many articles, they say this program without "volatile" will not successfully shutdown because this loop while (!shutdownRequested) will be optimized to while(true) by Java compiler if the value of the variable shutdownRequested is not changed inside the loop. But the result of my experiment does not stand for that.
I assume you mean you have a setup something like this:
final Worker theWorker = new Worker(); // the object you show code for
new Thread(new Runnable() {
public void run() {
theWorker.doWork();
}
}.start();
try {
Thread.sleep(1000L);
} catch(InterruptedException ie) {}
theWorker.shutdown();
And what you found is that the shutdown works even without volatile.
It's typically the case that this is true: non-volatile writes may be seen eventually. The important thing is that there is not a guarantee this needs to be the case and you can't rely on it. In practical use you may also find there is a small but noticeable delay without volatile.
Volatile provides a guarantee that writes are seen immediately.
Here's some code that might reproduce the HotSpot optimization we discussed in the comments:
public class HotSpotTest {
static long count;
static boolean shouldContinue = true;
public static void main(String[] args) {
Thread t = new Thread(new Runnable() {
public void run() {
while(shouldContinue) {
count++;
}
}
});
t.start();
do {
try {
Thread.sleep(1000L);
} catch(InterruptedException ie) {}
} while(count < 999999L);
shouldContinue = false;
System.out.println(
"stopping at " + count + " iterations"
);
try {
t.join();
} catch(InterruptedException ie) {}
}
}
Here's a quick review if you don't know what HotSpot is: HotSpot is the Java just-in-time compiler. After some fragment of code has run a certain number of times (from memory, 1000 for desktop JVM, 3000 for server JVM), HotSpot takes the Java bytecode, optimizes it, and compiles it to native assembly. HotSpot is one of the reasons Java is so lightning fast. In my experience, code recompiled by HotSpot can be easily 10x faster. HotSpot is also much more aggressive about optimization than a regular Java compiler (like javac or others made by IDE vendors).
So what I found is the join just hangs forever if you let the loop run long enough first. Note that count is not volatile by design. Making count volatile seems to foil the optimization.
From the perspective of the Java memory model it makes sense that as long as there is absolutely no memory synchronization HotSpot is allowed to do this. HotSpot knows there's no reason the update needs to be seen so it doesn't bother checking.
I didn't print the HotSpot assembly since that requires some JDK software I don't have installed but I'm sure if you did, you'd find the same thing the link you provided recalls. HotSpot does indeed seem to optimize while(shouldContinue) to while(true). Running the program with the -Xint option to turn HotSpot off results in the update being seen as well which also points to HotSpot as the culprit.
So, again, it just goes to show you can't rely on a non-volatile read.
Volatile is for threading. It basically tells the threads the variable can change anytime, so anytime it wants the variable it can't rely on a cached copy it must re read it and the update it after changing it
Volatile in many senses is due to the local caching that a processor can do on a per-thread basis.
for example, lest say we have a processor with 4 threads running your java program (albeit a massively simplified example since a processor would do WAY more than just this). Lets also assume that each of those 4 main threads have access to a local cache (not to be confused with a main processor cache). So, if you just made that variable static, and all 4 threads were reading from that variable, they could all potentially put that variable in their local cache. Alright, great, access time is improved, and everything is faster. So, at the moment we have the following situation:
Thread 1: has a local copy of the variable
Thread 2: has a local copy of the variable
Thread 3: '' '' '' '' '' '' ''
Thread 4: '' '' '' '' '' '' ''
Alright, now, lets say that Thread 1 goes in and changes the ACTUAL variable, not just the copy. Thread 1 knows about the change immediately, but threads 2-4 could still be working on the value of the old, cached version of the variable since they haven't checked for any updates yet.
Now, to fix this type of situation, you can attach the 'volatile' keyword to the variable, which essentially tells it to broadcast its new value to all of the threads in the program IMMEDIATELY so that any operations on all of the threads will have the exact same value. Of course, this does incur some overhead, so something that is volatile will be a touch slower if it is modified often. Since your program is not multi-threaded (that I can tell) you'll see little to no difference using volatile or not. It's simply a trivial (and pointless) extra 'command' for the variable in single-threaded environments.

Variable depth recursion in Java

So I'm doing a little experiment on exactly how far recursion can go in the Java language since I'm taking a class on concurrency and learning about Java's threading mechanisms. Right now I'm running a Intel i5 Quad-core with 2.8 GHz and 4GB of RAM. I'm running on Windows 7 with x64 and in Eclipse with the standard JRE? Not sure about that last part I just downloaded something from Sun's website.
Anyway,
public class StacksizeTest implements Runnable {
int depth = 0;
public void run()
{
try
{
doOverflow();
}
catch (StackOverflowError e)
{
System.out.print("Overflow ocurred at depth " + depth + ".\n");
}
}
void doOverflow()
{
depth += 1;
doOverflow();
}
public static void main(String argv[])
{
Thread mt = new Thread(new StacksizeTest());
mt.start();
mt.run();
}
}
I'm also running with the default call stack size, which im pretty sure is 512Mb according to the settings file.
So when I run the program and start a new thread I keep getting variable depths, as well as the print statement printing twice. The print statement makes sense I think because it should be running mt on a new thread. What I'm confused about is if I exclude .start() and just call .run() the "depth" is always the same (about 11,500 or so), but when I use .start() I'm getting variable depths. a couple have been 22789, 22330, and 22381. I'm having difficulty understanding why this is. Could someone possibly shed some light on this issue?
Thanks,
Matt
The call to .start() will start a new thread with run(), then you're calling run() again on the main thread. So you've got two stack depth threads running at the same time. Since you've also got a shared variable counting the depth that's not protected by a synchronized mutex, you've got a classic variable contention problem.
In order not to confuse the issue with variable contention, I would limit yourself to one running instance of the stack depth checker.
When you call start() you're firing off the method asynchronously, so you're running it twice because start() eventually makes a call to run(), and in addition you're calling run() yourself, so you've got two threads incrementing your depth counter. Eliminate the start(), and you get your smaller count because you're only running a single thread.
EDIT: I just saw Greg's answer. I like his more.

Categories