What can cause this Java behaviour? - java

My project generates some text/binary files. If I run it normally, some files will have a pretty low size ( which indicates something went wrong ). If I run it from debug mode ( stepping through code ), the files will be generated correctly.
What can cause this behaviour? I'm pretty sure I don't have any unclosed files.
EDIT: I've gone through the code in a more focused way, and I've found the problem. At one point in time, the files get compressed, and this explains the decrease in size. I'm stupid :)
A moderator can close this question if he sees fit.

Try adding:
System.gc();
try { Thread.sleep(4000); } catch (Exception e) {}
System.gc();
...at the end of your program. If the problem goes away then you did forget to close() a file. The above code is no solution, it is a hacky attempt to increase the likelyhood finalizers will run.

Is your code multithreaded? Are you trying to read something that you haven't given another thread a chance to finish constructing, which doesn't manifest when you're stepping through it?

Do you call some kind of "read" method, to read from a file, for example, and assume that you will always get back the number of bytes that you request?

Related

My java program freezes every now and then and may have a memory leak. Is my telemetry useful?

I began learning java recently (with the extra free time i have now) and wrote code for a game called torn using netbeans 8.2. This code is a runnable that continuously retrieves data from the site and stores it for later use. It was freezing mid-run, and i was told that adding a connect timeout and a read timeout for the url connection might help. I did that and it is currently running again (so far so good), and am waiting to see if that problem will happen again or not.
My question is about finding memory leaks. I read that the number of surviving generations is an indicator of whether there is a memory leak. This is a screenshot of the telemetry after a few hours of running. The code for the project is also available (OtherFactionsStats.java is the main class). (Any notes about improving my code are very welcome as well :D ). I appreciate the help.
I think that I finally found your resource leak: in LogFactionPersonalStat on line 154 you open a file with in = new BufferedReader(... that never is never closed.
I suggest that you learn about try with resources.
The code in the same file, lines 128 to 130 for example would change from
FileWriter file = new FileWriter("" + path + completed); //set completion status to incomplete
file.write("0"); //zero means not yet complete
file.close();
to
try (FileWriter file = new FileWriter("" + path + completed)) { //set completion status to incomplete
file.write("0"); //zero means not yet complete
}
Not a big change, but now you cannot forget the close the FileWriter (or BufferedWriter or BufferedReader)
One other note: RunUpdate line 53 looks very suspicious (this pattern is repeated several times):
Logger.getLogger("Error reading from file");
Here you create a looger for "Error reading from file", but you never use that logger to write anything into the log.
You probably meant to write something like
Logger.getLogger(OtherFactionsStats.class.getName()).severe("Error: Possible timeout or problems with file");
or
Logger.getLogger(OtherFactionsStats.class.getName()).log(Level.Severe, "Error: Possible timeout or problems with file");

printStackTrace() in a finished product. When and why?

I've come to the conclusion after reading from many sources that using printStackTrace for error handling is bad practice. Here's one.
Now I'm struck curious: in what cases is printing the stacktrace a valid solution? For the sake of the argument, let's assume we aren't working on a system such as a microwave or a banana, but a basic out-of-the-shelf PC.
The reason I'm asking this could be seen as a question in itself, but I'll tell you about it anyhoo:
I'm developing a snake-like game that can be played with AIs, and is intended for that purpose. All such AIs should extend an abstract class called SnakeLogic. All such AIs should also reside in their standalone .jar archives in a specific folder, from where the main program can find them and list them using classloaders.
The user can then choose one of his/her AIs from a list, should all stars fall in line, and play a game with this AI.
Now, I have a method in my main program that gets the next move from the AI like so:
public void startGame(int speed) {
gameInterface.showWindow();
Runnable moveCmd = () -> {
try {
for (Player player : snakeGame.getPlayers()) {
if (player.isDead()) {
continue;
}
String move = player.getLogicHandler().getMove();
Direction direction = Direction.directionFromString(move);
snakeGame.makeMove(player, direction);
}
gameInterface.getFrame().repaint();
snakeGame.wait(speed);
if (snakeGame.gameOver()) {
stopGame();
}
} catch (Exception ex) {
ex.printStackTrace();
stopGame();
}
};
/* moveSchedule is an instance of ScheduledExecutorService */
moveSchedule.scheduleAtFixedRate(moveCmd, 1000, speed, TimeUnit.MILLISECONDS);
}
I'm not going to get too involved with the code above. I'd like to draw your attention to the try-catch statement, however. As you can see I print the stacktrace and end the game, should an exception occur somewhere during the execution of the moveCmd runnable. This is the source of my curiosity: If I don't print the stacktrace like this, or if I remove the try-catch entirely, I never get any errors in the case of a runtime exception during the execution of that block. Why? Is it because it's wrapped inside the runnable? Note also that the line snakeGame.makeMove(player, direction); doesn't call any code in the main program; snakeGame is an instance of a SnakeLogic, which resides in an external .jar.
Why don't I get any errors if I remove the try-catch? Also, in this case, is printing the stacktrace a good idea?
I understand this imposes two questions for you: the topic and the above. I want to emphasize the topic, so don't get too sidetracked with the second question; though insight is duly noted, there's nothing broken in my code.
You need to shift your thought process a bit when dealing with error and exceptions. It is always a good practice to print the error trace. Now the question is where to print. by default printStackTrace prints to your standard console. of course you can redirect that output to a log file like Tomcat does but that is a work around, if you ask me.
In production and pre-prod systems and even in distributable spftware where you distribute a desktop application to users for running on PCs you may or may not have dedicated access to console. Further more what prints on console is lost once the console is closed or app finishes. You need to persist the errors somewhere for analysis later. Normally folks design the app to zip and send error logs periodically to developers for analysis.
Now if you think about the whole scenarios the bottom line is to preserve the errors somewhere for analysis later. So usually do it in a rotating log file or in DB. Console wont suffice. Thus incidentally the catch block should have a log statement to log the exception.
The problem with Exception.printStackTrace() is that it writes to your console (most probably) which is a synchronous operation. Not to mention that writing to console is slow in most platforms. You dont want to hold off your execution thread until the full stack trace is written. So its better to hand it over to a log framework like log4j which has the ability to write the complete stack trace into to file asynchronously (other appenders are available), so that the execution thread returns immediately to the callee and yet the log contains necessary details.
So its a question of synchronous write or asynchronous write. As Nazgul pointed out, you have to log exceptions in a system for later analysis where ever applicable.
NotE: A problem with asynchronous logging is that if the process dies abruptly, like in kill -9 or system powered down, you may loose the buffered content before OS has chance to write it to disk

why did I get IllegalThreadStateException after calling this.interrupt()?

try {
this.interrupt();
} catch (IllegalThreadStateException e) {
e.printStackTrace();
}
I found out that an IllegalThreadStateException was thrown by putting print statement, no stack trace was printed. I have tried searching existing threads about Thread.interrupt() and IllegalThreadStateException, but didn't get much out of them. I am using CDLC 1.1, if it helps. thank you very much!!
CLDC 1.1 is supposed to support interrupt(), but CLDC 1.0 didn't. Maybe your particular implementation didn't feel like adding this support, and fakes it by throwing a runtime exception.
If no stack trace is printed, it sounds like there error is happening (and being handled) elsewhere. Can you step through the code in a debugger and see if that interrupt is triggering another thread to have a problem? It would have to occur with the process of executing interrupt().
In our IDE, I would put a breakpoint on that line, hit F5 to step inside the method call, then continue stepping inside until I found the problem. Along the way, if I get to a point where there is no source code I would download the related source jar file and point the debugger to it (which sounds involved but only takes about 2 minutes).
Hope that helps in some way,
-gMale

Can i start a thread in a catch in JAVA

I am trying to solve the collatz conjecture.
I am using HashMap and Vector classes. I have to iterate the loop 2 147 483 648 times, but after I store 8,438,409 values in HashMap I'm getting an OutOfMemoryError.
I'm running the program in Eclipse and have set -Xmx1024m option, but it didn't help. So, I'm catching the above error and trying to start a thread which would take the control to different class and start executing.
However, the thread is not starting. I've put System.out.println("We are here"); statement in it and it's never printed to the console. Can someone help me with this?
Thanks
funny
You don't want to start a thread in your catch {} block. That's trying (and failing) to treat the symptoms while ignoring the cause entirely.
What you want to do is stop that OutOfMemory error from occurring. Your options are to increase the heap size, or use less of it.
You have stumbled onto the difference between an exception and an error in java. Both errors and exceptions descend from throwable but just catching an exception will not catch an error. However errors are usually pretty serious and are difficult if not impossible to recover from see. When to catch java.lang.Error?
Yes you can start a thread in a catch block.
However, you probably won't be able to start a thread if you're getting an OutOfMemoryError. OutOfMemoryError means you're running out of heap space, and all threads use the same heap space (and in fact, creating a new thread will use up some of your already diminished heap).
You shouldn't need to iterate over every value to solve a question based on the collatz conjecture. I'd assume you are trying to calculate each value. This is an approach that I tried but ran in to the same thing (though, I was using .net).
Rather than trying to solve the technical problem, I'd like to suggest that you alter your approach.
Note: I realized, I assumed (with no cause), that you are trying to solve a ProjectEuler.net question (or the alike). If this is not the case, my solution may not be viable.
Yes,
there is no restriction on starting a thread in a catch block. However, the nomal behavior when capturing an exception is show it to users, logging, throw another exception instead, close your application.
As said for the others, in your case you're trying to catch a java.lang.Error, which is not an Exception, and you don't have guarante of the next line of code execution.

Have program recognize it crashed last time?

What is the best way to have a (Java) program recognize it crashed last time it ran and show a message along the lines of "it looks like this program crashed on you last time. Report this problem here: bla#foo.com ...."
Is there a recommended way of doing this? (Bad?) ideas I had would be:
Have the program store a temporary key file at startup and then delete it when closing regularly. If the file exists at startup, show the message.
Recognize deadlocks and store an "error file" in this case. If an "error file" exists at startup, show the error message and move the file into an archive or something similar.
There are three reasons why a Java program can crash:
Unhandled RuntimeException. This is easy to solve with a try-catch in main.
Unhandled Errors. These are rare but can be caught in main also. I usually catch Throwable in main. See below for a template.
If you use threads, then look at Thread.setDefaultUncaughtExceptionHandler().
Bugs in the VM, or program killed by the user, or hardware violent shutdown. These will lead to a crash which can't be caught. Here, your best option is to create a flag file somewhere with new File(...).deleteOnExit(). Java will clean it up for you if it gets a chance.
The problem with deadlocks is how to detect that you have a deadlock. I haven't seen a consistent way to do that, yet.
import org.apache.commons.lang.exception.ExceptionUtils;
public class Demo
{
public static void main (String[] args)
{
try
{
Demo obj = new Demo ();
obj.run (args);
System.out.println ("Done.");
}
catch (Throwable t)
{
ExceptionUtils.printRootCauseStackTrace (t);
}
}
}
Crash as in an uncaught exception? The use a Thread.setDefaultUncaughtExceptionHandler, and display the message as part of the crash.
On the first idea, how do you handle multiply instances of the applications running at the same time? (Also think about multi-user environments).
Recognize deadlocks - How often are deadlocks the problem? I guess you could monitor the thread states on all the "key" threads.
You then have external forces killing the application, should they be considered a problem that you should report? After all your application was not at fault in this case.
Finally, always store an "error file" in the form of a log. Use a proper logging framework (i.e. Java Logging or Log4J). You could check the last lines of this for a signal that the application exited normally but again you will need to be careful in multi-instance environments.
A variant of the first solution you propose is common enough on Un*x for processes: store the pid file of a running process in a file at startup. When the program is launched again you can check if this file still exists (and even if the process with this pid is running).
With Java you could probably adapt this idea using Threadid defined in ThreadMXBean. But any file would do. A file that contains a key as you propose seems a good enough way. You could also put some usefull information in it like last execution time. If it's still there at startup the program didn't stopped cleanly.
It could also become something like a launch log file that trace program events including startup and clean stops, and maybe locks.
What I do is redirect System.err to a file, so that any error message (like crashes) end up in a file I can later process...
The code to do this is quite simple...
String errLog = "c:\\myLog";
try
{
java.io.PrintStream err = new java.io.PrintStream(new java.io.FileOutputStream(errLog));
System.setErr(err);
}
catch (java.io.FileNotFoundException fnfe) {}
I'm going to mimic Marcos here. Create a configuration or log file that will host the last error message and last run date of the program. Then read that file during program load.
Many of these answers are about tracking exceptions that caused your app to quit working.
Another possibility is that the application just quit (i.e. user killed it, computer shutdown, power outage, etc.). I think your temporary key idea will work for that. It's similar to how text editing programs, such as vi or Word, automatically create a special copy of the file being edited. Upon opening it checks to see if the special copy exists and asks if you want to recover the file.

Categories

Resources