i thought about the fact, that using try and catch is useful to prevent crashes if there are mistakes, but i was curious if there is any impact at the performance if i overuse the try and catch block.
To resume: Is there any impact at the performance if i use try and catch(nearly) everywhere?
Exception throwing/handling does come with a slight performance penalty (the exact amount varies greatly by the exact scenario), but performance shouldn't be your first consideration.
Correctness: First of all, make sure that your code does what it needs to do. Don't treat normal use cases as exceptional, for example if a user types in an incorrect value in a field, that's nothing special, no need to throw exceptions for that. But if something is genuinely exceptional (like you can't connect to the database), and you can't deal with it at the point it occurs, throw an exception. And if the exception comes from "below", from a JDK class or a third party library, you have no other option than to handle it.
Readability. Constantly catching and re-throwing exceptions can make your code near impossible to follow, debug or maintain. The same goes for swallowing exceptions without a trace. What you should aim for instead is a consistent strategy for handling exceptions. Basically you should only handle exceptions on the level where you can do something about them.
Performance. This should be your last port of call, once you get the first two sorted. It is unlikely that you'll ever be in a place where your code is correct and readable, and still exception handling is the main bottleneck of your application, but if you do get there, you can try returning error codes rather than throwing exceptions, or completely restructuring your code to avoid them.
I think the main hit to performance you are going to see (assuming the code in question is executed at a very high frequency) will be from garbage collection.
One trivial example (this you do actually see in production code every now and then ...) would be having password verification logic like:
if (!password.equals(correctPassword)) {
throw new IncorrectPasswordException();
}
and then ...
catch (final IncorrectPasswordException ex) {
//some output or so
}
... instead of simply never throwing anything and just handling this via conditionals. You will eventually have to clean up all those IncorrectPasswordException from memory.
In this case overusing exceptions actually will become pretty costly by turning simple evaluations into object instantiations that cost you memory and even more importantly eventually cost you precious CPU cycles for reclaiming that memory via garbage collection.
Related
I have tried looking for an answer to this on other threads, but so far I have only seen threads that state that catching Throwable is bad. My question is, is there ever a reason why you would WANT to do this and then do nothing in the catch block except print out the stack trace?
I was recently brought onto a project and given the task of cleaning up the error handling of an existing set of classes for a RESTful service. Several of the helper service classes have try/catch blocks that only catch Throwable and print out the stack trace, as shown below:
class MainService {
SubService1 s1;
SubService2 s2;
public doMainService() {
}
}
class SubService1 {
public int findSomething() {
try {
// Do Something
} catch (Throwable t) {
t.printStackTrace();
}
}
}
class SubService2 {
public int findSomethingElse() {
try {
// Do Something
} catch (Throwable t) {
t.printStackTrace();
}
}
}
Is there a case that this is acceptable? Would it be better for the methods to throw Exception and not have the try/catch blocks?
This is almost never a good practice for a variety of well known reasons.
In particular, it doesn't distinguish between checked and unchecked exceptions and errors. More importantly, one of the effects of this code is allowing the application to execute beyond the exception handler which may result in all kinds of strange behavior due to violated invariants. In other words, since the exception caught may be really anything including violated assertions, programming errors, thread interruptions, missing classes, I/O errors, OOM conditions and even library and VM bugs, the program state is practically unpredictable beyond the exception handler.
In some rare situations broad exception handling may make sense. Imagine a server handling multiple independent requests. You may not want to crash due to a problem encountered while serving one of the requests. Since you do not rely on the state left after the exception handler, you can simply print the stack trace and let someone investigate while the server continues serving other requests.
Even in these situations one should carefully consider whether errors, e.g. VirtualMachineError should really be caught.
One reason that I think people do this is just because Java forces you to either surround calls that throw with a try/catch block, or add throws to the method declaration.
If you "know" that you're not going to have an exception occur, then it's kind of a way to prevent it from going up the chain (cause if you do throws, who ever calls your code needs to surround with a try/catch and so on), but if something does occur it'll dump it without crashing.
You might do that if you don't know any other way to get the stack trace and you want to know how you got to your current location. Not a very good reason, but a possible one. This doesn't seem to fit what you're looking at though; you seem to have been given code which doesn't crash but also doesn't do a good job with error handling.
I use it to see exactly where my program is crashing. So basically just for debugging. Also just to see if it's flowing in the way expected.
It is possible that they wanted to see the stack trace without crashing the program.
For example it can be appropriate for code executed by a thread to log exceptions but otherwise do nothing when it is unacceptable for the thread to crash since the next iteration (say where threads are taking items from a queue) may work as expected. This depends on the use case, but for a server you generally want the threads to be bullet proof and log any errors, instead of halting any further processing (but use cases may vary).
Most simplest example we come across in your problem is when it comes to close an input stream.Follwoing is the method declaration in InputStream class.
public void close() throws IOException
Althoug there is a possiblity to throw an exception when we call this method it would be no harm for the program execution.(Since we will not use that InputStream further) In that case we should only log the error and continue the program. But if you find out an exception which change the states of an object and then you must think about recovery code or halt execution.
Never do this (e.printStackTrace()). many IDE's default to it, but its horrible (many apps run with stderr redirected in ways that are not accessible, and thus, never seen). rules of thumb:
if you truly don't care about the exception (never, ever, ever, ever will care), catch it and do nothing with a big comment which says "we really, really don't ever care if this exception gets thrown"
if you never expect an exception to actually be thrown (the interface defines a checked exception, but you know the impl doesn't actually throw it), rethrow the exception as something like new UnsupportedOperationException("this should never happen", t) (that way if/when the underlying impl gets changed you find out about it sooner rather than later)
if you expect that the exception is unlikely, and you usually will not care about it, log it with a proper logging infrastructure (log4j, commons logging, or java.util.logging). that way it will most likely make it somewhere that you can see later if you decide that you actually do care about the exception after all.
Imagine a simple banking application wherein a use case of fund transfer is being realized. While writing transfer fund operation, the programmer/designer has following two options
Write an operation to check if there are sufficient funds or not and return a Boolean based on which the subsequent fund transfer option will be carried out. This require creating two function viz. the checkSufficientFunds() and transferFund()
Write a single operation which itself checks if the funds are sufficient or not. This will throw an checked Exception if there are no sufficient funds and calling method have to handle this.
I understand that this is an oversimplified scenario. My question is, in theory, what are the performance implications (Memory and CPU) of these two approaches? How do they compare?
The performance difference in the current JVMs should be negligible. However, stick to the rule that exceptions should be used in exceptional situations. It is a normal flow not to have sufficient funds, so I would use a method public boolean transferFund() that returns true if successful, and false otherwise. This suggestion violates the command/query separation, but I think it's fine.
At runtime, try-catch blocks doesn't significantly affect performance. Only when an exception occurs and in theses cases you must handle the exception anyway. But you have to use exceptions only when they are required (when the app is unable to preceeed normally).
This assignment is more about atomic operations. In the first scenario it is possible to overdraft an account whereas in the second you roll everything back (or should).
In terms of performance any time you generate a stack trace that consumes memory and time. Iirc it makes an execution path 70x more expensive.
If I was doing a code-review and someone motivated the choice between using exceptions vs method calls by performance considerations, I would down-mark that developer. It's a text-book case of sub-optimization and a waste of time. Optimize where it matters and has a measurable impact. Don't shave milliseconds at the cost of code quality and robustness.
As for this case - some people like to use exceptions as a flow-control mechanism. I don't. Exceptions, in my view, are used to indicate reaching an unexpected state. Often, this is analogous to an error. Checked exceptions imply that the state is something that could conceivably be recovered from within the scope of the current transaction or conversition. An unchecked exception implies that there is no reliable recovery and the system should alert the user.
The performance impact is unlikely to get great enough to worry about. However, I would still recommended using Exception for exceptional situations. In this case you don't need two methods. You can have
boolean transferred = transferFundsIfAvailable( ... );
A reason using two methods is undesirable is that it could cause race conditions, even if the individual methods are thread safe. Say you have
if(checkSufficientFunds()) {
// another thread transfers funds
transferFund(); // but there is not enough any more
}
Also you could forget to call the check first. You are better off without it.
Some code simply call
catch (InterruptedException ex) {}, why?
This is usually a sign that the developer didn't know how to handle the Exception and thus just ignored it.
This is the sort of bad behaviour that results in some saying checked exceptions are a failed experiment. IMHO Developers should just learn to handle exceptions.
A better way to handle this exception is to either
pass it to the caller. i.e. don't catch it.
call Thread.currentThread().interrupt() so the interrupt is not lost.
If such an exception should be impossible, wrap it in a throw new AssertionError(ex)
That is used in situations where an exception may occur but the response to the exception is the same as normal continuation from the try block. A common example is calling sleep(). (However, that's actually often a bad example because being interrupted often signals that an operation should be abandoned.)
InterruptedException is what's called a checked exception. When added to a method you want to call, it's a way of signifying that you must account for this situation, namely that the time you need to process the results of the call may be pre-empted by another thread in the system.
Assume for the moment that you have 6-7 statements in a try block, and you assume they will run in a more or less atomic fashion. Among those statements is one that relies on thread-aware behavior. If that call is pre-empted, your subsequent statements won't run, and you'll have to handle the consequences.
People have all sorts of reasons for catching this exception but taking no action. I can't think of many good reasons for doing this, unless I can clearly show that being interrupted doesn't create an undesirable side-effect in my code. Given any example piece of code that shows this behavior, I would guess no catch logic was included because a) the programmer had no plan for dealing with it; b) the programmer merely wanted to step past the check so the code compiles.
On a recent project I recommended catching a RuntimeException within a test harness code and logging it. The code processes a series of inputs from a database, and I do not want the test to stop due to failure of any one input (Null values, Illegal arguments, etc.). Needless to say, my suggestion triggered a passionate discussion.
Is catching any kind of RuntimeException acceptable? If yes, what are other scenarios where it is OK to catch RuntimeExceptions?
You catch RuntimeException for the same reason that you catch any exception: You plan to do something with it. Perhaps you can correct whatever caused the exception. Perhaps you simply want to re-throw with a different exception type.
Catching and ignoring any exception, however, is extremely bad practice.
Unless you can correct a RuntimeException, you don't want to catch it...
...only true from a developers point of view....
you have to catch all exceptions before they reach up to the UI and make your user sad. This means on the "highest level" you want to catch anything that happend further down. Then you can let the user know there was a problem and at the same time take measures to inform the developers, like sending out alarm mails or whatever...
It is basically considered a data/programming error that could not be forseen, thus you want to improve future releases of the software while at the same time take the user by the hand and move on in a controlled manner...
RuntimeException is intended to be used for programmer errors. As such it should never be caught. There are a few cases where it should be:
you are calling code that comes from a 3rd party where you do not have control over when they throw exception. I would argue that you should do this on a case by case basis and wrap the usage of the 3rd party code within your own classes so you can pass back non-runtime exceptions.
your program cannot crash and leave a stack trace for the user to see. In this case it should go around main and around any threads and event handling code. The program should probably exit when such exception occurs as well.
In your specific case I would have to question why you are having RuntimeExceptions occur in the tests - you should be fixing them instead of working around them.
So you should guarantee that your code only throws RuntimeExceptions when you want to have the program exit. You should only catch RuntimeExceptions when you want to log it and exit. That is what is in line with the intent of RuntimeExceptions.
You can look at this discussion for some other reasons that people give... I personally haven't found a compelling reason in the answers though.
In my code 99% of my exceptions are derived from runtime_exception.
The reasons I catch exceptions are:
Catch Log and Fix problem.
Catch Log and Generate a more specific exception and throw
Catch Log and rethrow.
Catch Log and Kill operation (discard exception)
User/request initiated action fails.
An HTTP request handler for example. I would rather the requested operation die rather than bring the Service down. (Though preferably the handler has enough sense to return a 500 error code.)
Test case passed/failed with an exception.
All exceptions not in the main thread.
Allowing exceptions to escape a thread is usually badly documented but usually causes program termination (without stack unwinding).
Years ago, we wrote a control system framework and the Agent objects caught runtime exceptions, logged them if they could and continued.
Yes we caught Runtime exceptions including OutOfMemory in our framework code( and forced a GC, and it's surprising how well that kept even quite leaky code running.)
We had code that was doing very mathematical things involving the real world; and from time to time a Not-A-Number would get in due to tiny rounding errors and it coped okay with that too.
So in framework / "must not exit" code I think it can be justifiable. And when it works it's pretty cool.
The code was pretty solid, but it ran hardware, and hardware tends to give screwy answers sometimes.
It was designed to run without human intervention for months at a time.
It worked extremely well in our tests.
As part of the error recovery code, it could resort to rebooting the entire building using the UPS's ability to turn off in N minutes and turn on in M minutes.
Sometimes hardware faults need to power cycled :)
If I remember, the last resort after an unsuccessful power cycle was it sending an email to it's owners, saying
"I tried to fix myself and I can't; the problem is in subsystem XYZ", and included a link to raise a support call back to us.
Sadly the project got canned before it could become self aware :)>
Personally, I've always been told that you want to catch all RuntimeExceptions; however, you also want to do something about the exception, such as running a failsafe or possibly just informing the user that an error occurred.
The last Java project that I worked on had a similar approach, at the very least, we would log the exception so that if a user called complaining about a bug, we could find out exactly what happened and see where the error occurred.
Edit 1: As kdgregory said, catching and ignoring are two different things, generally, people are opposed to the latter :-)
We all know that checked exceptions and RuntimeExceptions are the two categories of exceptions. It is always suggested that we handle (either try-catch or throw) the checked exceptions because they are the programming conditions where unfortunately programmer can not to do anything on its own;
Like FileNotFoundException it is not the programmer who puts files on user's drive if program is actually trying to read the file 1.txt which is supposed to be there on f:\ of user with the statements:
File f11 = new File("f:\\1.txt");
FileInputStream fos = new FileInputStream(f11);
If the file is found it's all ok, but what happens in the other case if the file is not found is that, program crashes down with 0 error from the user. In this scenario programmer did not do anything wrong. This could be a checked exception which must be caught for the program to continue running.
Let me also explain the second scenario with which the concept of RuntimeException will be clear. Consider following code:
int a = {1,2,3,4,5};
System.out.println(a[9]);
This is poor coding which generates the ArrayIndexOutOfBoundsException. Which is an example of RuntimeException. So programmer should not actually handle the exception, let it crash the program, and later fix the logic.
You catch RuntimeException when you want to process it. Maybe you want to rethrow it as a different exception or log it to a file or database, or you want to turn on some exception flag in the return type, etc.
You catch RuntimeExceptions (in any language: unexpected exceptions/“all” exceptions) when your program is doing multiple subtasks and it makes sense to complete every one you can rather than stopping on the first unexpected situation. A test suite is a fine situation to do this — you want to know which of all the tests failed, not just the first test. The key characteristic is that each test is independent of all the others — it doesn't matter whether a previous test doesn't run because the order is not significant anyway.
Another common situation is a server; you don’t want to shut down just because one request was malformed in a way you didn't expect. (Unless it’s really, really important to minimize the chances of inconsistent state.)
In any of these situations, the appropriate thing to do is log/report the exception and continue with the remaining tasks.
One could vaguely generalize to any exception: it is “appropriate to catch” an exception if and only if there is something sensible to do after catching it: how your program should continue.
If a client can reasonably be expected to recover from an exception, make it a checked exception.
If a client cannot do anything to recover from the exception, make it an unchecked exception.
Here's the bottom line guideline.
From Java Docs. Please read this Unchecked Exceptions — The Controversy
I use a Windows OS library to manipulate image files. Sometimes it crashes deep inside it for no apparent reason—all the inputs are reasonable and its not a threading issue. The crash is memory A/V.
So, what are the down sides to something like this:
try {
pFoo = OsAPIThatCrashes();
} catch {
pFoo = NULL;
}
Will that even work? We don't use exceptions anywhere else in our code.
For one, while we all like to bash MS for the flaws in their software, IME in 99 out of 100 cases the problem wasn't a bug in the OS, the compiler, or the standard library, but in the code calling it. Whatever Win API you're using - it's tested a lot more thoroughly than most (if not all) code ever using it.
Further, try/catch catches C++ exceptions, not OS exceptions. (Earlier versions of VC did this wrong, but later ones have the right default.) So try/catch won't catch an AV. That said, VC provides ways to catch OS exceptions. I think it's called structured exception handling and centered around __try/__catch, but I'm not sure since I have never used it. However:
Once your application ran into an AV, all bets are off. An AV is just one way for undefined behavior to manifest itself and once you (or the API code, however unlikely that might be) invoked undefined behavior, there's nothing you can assume about the state of your application. You should not continue.
To sum it up: You should try to find out what you did wrong. A good way to do this is trying to boil the problem down to a small piece of example code that reproduces the problem. In 90% of all cases, this will reveal the error. If even a small piece of code reproduced the problem and you still don't know what the problem is, you have a nice repro case to come back with (or to throw at MS support). IME, in 9 of those 10% someone else points out your error, and only the remaining 1% will reveal a bug you didn't make yourself.
Chances are that this won't do any good -- it would only help if the OS API threw an exception that you could catch. If it was doing that, and you weren't catching the exception, you'd normally get an exit from the application, with an error message to the effect that it had exited by throwing an exception that wasn't caught. Unless you're seeing something on that general order, there's very little chance that wrapping the call in a try block will do any good.
Depending on the OS, you might be able to use a native exception handling mechanism to accomplish a bit more -- for example, under Windows, you can catch things like page faults using structured exception handling. Again, it's not entirely clear whether this will do any good though -- if an unhandled exception is the source of the problem, it may help, but if the code has a bug where (for example) value X==10 and value Y == 20 leads to an infinite loop, or something on that order, you're probably going to have to pin down when the code crashes, and assure that never arises.
The internal state of the library is probably bad at this point, so continuing to use it is risky. Best to fix it, crash, or use a different library. Sometimes life just sucks.
While the win32 API is a C library and doesn't use exceptions, MSVC can implement certain things as exceptions (such as division by zero) that aren't required to be done that way (by the C++ standard). So: it depends.
Your best bet is finding out what's causing the problem and fixing that.
You may like to explore Structured Exception Handling. The structured exception handling and termination handling mechanisms are integral parts of the Windows operating system. MSDN reference
try/catch is for C++ exceptions what you need to use is
__try {
} __except(EXCEPTION_EXECUTE_HANDLER) {
}
But all that will do is eat the exception, it won't fix the problem and could leave the library (or your app!) in an inconsistent state. If the exception is a floating point exception, then you have a good chance of ignoring it an moving on, but if it's an access violation, then you may be just delaying the crash.
If you can nail it down to a specific type of exception, you can catch and eat only that type
long WINAPI filter(EXCEPTION_POINTERS * pex)
{
EXCEPTION_RECORD * per = pex->ExceptionRecord;
DWORD dwCode = per->ExceptionCode;
if (EXCEPTION_DATATYPE_MISALIGNMENT == dwCode)
return EXCEPTION_CONTINUE_SEARCH; // let a handler above us deal with it.
else if (EXCEPTION_FLT_DIVIDE_BY_ZERO == dwCode)
return EXCEPTION_EXECUTE_HANDLER; // Eat this one
return EXCEPTION_CONTINUE_SEARCH; // let all the rest on through...
}
__try {
...
} __except(filter(GetExceptionInformation())) {
}