Practice of exit(0) in C and System.exit(0) in Java - java

To use exit(0) in C is not a good practice, if there are alternatives, since it does not free resources for example. But to use System.exit(0) in Java - how is it here? Could one trust the garbage collector in this context?
C language:
exit(0);
Java:
System.exit(0)

But to use System.exit(0) in java - how is it here? Could one trust the garbage-collector in this context?
When you call System.exit in Java, the garbage collector is not normally run1. However, in any JVM that I've ever heard of, there is something else that reclaims all of the objects that were allocated. (Typically it is handled at the operating system level.)
The fact that the GC doesn't run is only significant if you are relying on object finalizers to so something important before the JVM terminates.
Hypothetically, if your Java application used JNI (etc) to call native methods, then those methods could access system resources that might be problematic. However:
As a general rule the operating system does take care of such things. At least it does for modern versions of Linux and UNIX, AFAIK.
The garbage collector has no knowledge of those resources anyway. If the OS can't reclaim them, then the Java garbage collector won't help.
If you did need to clean up such resources acquired by a Java program (via native code) then the best approach would be to implement the cleanup in native code methods, and use a "shutdown hook" to run them. The shutdown hooks will be run if you call System.exit.
1 - A garbage collection will be performed on JVM exit if you have previously called runFinalizersOnExit(true). However, this is a deprecated method. The Oracle site explains it like this:
Q: Why is Runtime.runFinalizersOnExit deprecated?
A: Because it is inherently unsafe. It may result in finalizers being called on live objects while other threads are concurrently manipulating those objects, resulting in erratic behavior or deadlock. While this problem could be prevented if the class whose objects are being finalized were coded to "defend against" this call, most programmers do not defend against it. They assume that an object is dead at the time that its finalizer is called.
Further, the call is not "thread-safe" in the sense that it sets a VM-global flag. This forces every class with a finalizer to defend against the finalization of live objects!
In short, this is a dangerous approach, and it won't directly deal with the kind of resources that the OP is worried about.

Think of it like this. In C, you are building your source code into a binary file that will execute on it's own only conforming to the rules of logical programming and the rules set by your OS. The OS however does not manage your memory for you. It handles events and sends information to the hardware that tell it how to run, nothing more, nothing less. In java, all code is compiled into java's own bytecode. Upon execution it does not actually at any time communicate to the OS. The virtual machine designed to run that bytecode is what does the talking. When you call System.exit (0), you are telling the virtual machine that the app you are running is coming to a halt, from there the machine handles IT'S OWN MEMORY which just so happens to include anything you did not already remove via the garbage collector but only if the VM is exiting as well. Hope that helps

Related

Releasing Memory Allocated by Native Libraries in Java

If you are running code that makes calls to a native library in Java, what is the usual way of freeing memory allocated by these libraries when the memory allocation should last for the lifetime of the object? In C++, I would use destructors, but Java never really had those and has them even less now.
The specific case I'm most interested in is JOCL, where I have an object that wraps a compiled OpenCL kernel and all of the arguments thereto that are always the same. Structures representing the compiled kernel and the arguments are all allocated on the library side, and JOCL provides a method clReleaseMemObject that you call to decrement a reference counter indicating when the object should be deleted (note that this is a bit different from directly freeing the memory, but I don't think substantially so in this case).
I presume that if the object is still around when the program terminates, everything is cleaned up by the OS, but I'm not so sure about about objects created in a thread. So:
If you want the native memory deallocated when the object is garbage collected, is there a proper place to call the method that releases this memory?
If the object is one that will last for the duration of a thread, is there a proper place to make this call, or is this even necessary?
What you can do is use a Cleaner. This is a more official API in Java 9 but is available in Java 1.4+.
Essentially you give it a Runnable to execute when the resource is cleaned up.
One advantage of using a Cleaner is you can call it to clean up deterministically, but if you forget or fail to do so, the GC will call it after it runs.
There isn't a safe way to clean up an object when a thread dies as the Thread object can live for the life of the program even if dead. A simpler approach is to clean up as you know it is not needed or after the GC determines it is not required.
Another approach is to use a reference queue and a background thread. It's not as elegant but works across Java 8 and later versions.

Good practice to call System.gc()

I read many articles about bad practice to call System.gc().
I understand that no guaranty at all that JVM will react on this call.
And I know that System.gc() is pretty good indicator of fundamentally broken code.
But, if I have web backend server and I need to process many resources at server load stage. And after load memory is full of garbage.
And I know that my server will be used only in Ubuntu with Hotspot JDK1.8 and this JDK reacts on System.gc().
Is it bad to call System.gc() only once after load and before I open server for users?
Is there someone who does the same thing?
There is no need to call it at all. It isn't guaranteed that it will do anything, and it is guaranteed that GC will be performed before an OutOfMemoryException can be thrown. And if it does do something it may waste CPU time.
It's fine to call System.gc(). Do use a memory analysis tool to check that it's helping in your case.
The spec can't guarantee any results since the vm might've just done a GC.

How to moniter memory allocated by some java method at runtime

I am creating a java program in which my class suppose A has it's some predefined behavior. But user can over-ride my class to change its behavior. So my script will check if there is some subclass than I will call it's behavior but what if he has written some blocking code or memory leak in his code.
This may harm my process. Is there is any way in java to monitor memory allocated by some method.
Please suggest.
but what if he has written some blocking code or memory leek in his
code
First of all i suggest you document your class well. Describe what the user is allowed to do and what not. Give use cases what to do(if possible).
For the blocking code part, if you have some timing issues, you could wrap the execution of the method in say a Future and let a ExecutorService execute the code. That way you will be able to cancel the execution if the execution takes too much time.
For the memory leak issue, well i guess you are not talking about memory leaks but increased memory consumption caused by calling the overridden method. Memory leaks in java are rare after all.
You will not be able to detect the memory consumption of a method, that's not how java works. Memory is global. What will you do if for example an external library is loaded(JNI), or some library in the classpath is called that will use more memory now? You just can not tell.
Other then monitoring the overall memory consumption, there is no other way(someone please tell me if i am wrong).
Oracle has quite a good document about solving memory leaks. It suggests that one should use NetBeans Profiler as a tool.
http://www.oracle.com/technetwork/java/javase/memleaks-137499.html
I believe you can use the same debugging API for checking against misbehaving code while it is running, but that will come with a performance penalty and is probably akin to killing a fly with a sledgehammer. I personally would not let anything like that to run in production. Instead I would rely on rigorous testing and peer review.
For external monitoring, you can use VisualVM or JConsole (part of JDK), for internal you can use the Runtime class:
Runtime rt = Runtime.getRuntime();
long totalMem = rt.totalMemory();
long maxMem = rt.maxMemory();
long freeMem = rt.freeMemory();
Via the Thread class, you can check the status of all threads. Never used it directly, because application servers or batch processing APIs doing their job... So, I don't need to reinvent the wheel. And I suggest to use tools like VisualVM...
EDIT: Watch also this thread: Why do threads share the heap space?
You cannot analyze the heap usage of a single thread. If you have problems with the execution of foreign code, you should sepearate it as good as you can from other threads and analyze the thread or heap dumps. This could be done as mentioned with VisualVM or JConsole which was also added by Oracle (or SUN).
Depending on what sort of behavior that the subclass can do, then we might think of options. For example, if it's a database related operation, we can force them to do connection clean ups, if it's file based, we can force them to read the file through your class and check for how big the file is, if it's any http call or some other streaming functionality, we can look at enforcing constraints accordingly.
If you're just worried about the heap size utilization and memory leaks there, you might want to look at http://java.dzone.com/tips/getting-jvm-heap-size-used which explains how to get runtime memory programatically. But then you'll have to do periodic checks and you can never be sure of whether a memory usage is caused by the subclass behavior.
I just found this while i was trying to build up an agent that records memory allocations:
In the post How to track any object creation in Java since freeMemory() only reports long-lived objects? it is specified that there is an open source project Java Allocation Instrumenter that you could use to register your own callback (it has examples too) and using that you are able to obtain what you need.
I started few days ago to work on a similar project and while researching i found your question and the below post.
I personally needed this kind of code in some unit tests to check if one allocates too many objects inside critical methods and found that using Runtime class was not appropiate because Garbage collector may interfere and the test recorded negative numbers for allocated memory.

What are some examples of non-critical resources?

A quote from Effective Java states that:
A second legitimate use of finalizers concerns objects with native peers. A
native peer is a native object to which a normal object delegates via native methods. Because a native peer is not a normal object, the garbage collector doesn’t
know about it and can’t reclaim it when its Java peer is reclaimed. A finalizer is an
appropriate vehicle for performing this task, assuming the native peer holds no
critical resources.
I've not done C++ before, though I'm vaguely aware that file handlers and database connections are critical resources. But what exactly does it mean for a resource to be non-critical?
Or rather, what are some examples of non-critical resources?
“Non-critical resources” don’t exist. The quote isn’t talking about non-critical resources, it’s merely talking about the absence of critical resources.
In a way, you could say that memory is a non-critical resource in a garbage-collected system. However, I’m not convinced that this would be correct (quite the opposite, in fact: managed resources can still be critical if they run out), and I’ve never heard this being said.
I don't think it's really the resource that's critical, despite the phrase used. I think it's recovering the resource that may or may not be critical, and the quote could be rephrased, "assuming it is not critical that the resource is freed".
If it's critical that the resource is freed by a particular point in program execution, after the object is unreachable but before the resource is needed for some other purpose, then a finalizer is inadequate. Instead you need some program logic to make sure it happens.
So, file handles or db connections are critical if you're worried that you might run out, they're not critical otherwise. If you've reached some limit of open DB connections, because the finalizers that would close your old ones haven't been run yet, and you try to open another DB connection, chances are it'll fail. The situation with memory is rather better, since if you've run out of memory because of unreachable objects, and try to create a new object, then the GC will at least make an effort to find something to finalize and free.
Thus, file handles and db connections should have a close() function that the user can call to free all resources in cases where the program logic is able to determine that the object will not be used again. Expecting the GC to close the connection via a finalizer isn't reliable enough. It also doesn't deal well with the possibility of a flush or commit failing, although that's a separate issue.

Good uses of the finalize() method [duplicate]

This question already has answers here:
Why would you ever implement finalize()?
(21 answers)
Closed 5 years ago.
This is mostly out of curiosity.
I was wandering if anyone has encountered any good usage for Object.finalize() except for debugging/logging/profiling purposes ?
If you haven't encountered any what would you say a good usage would be ?
If your Java object uses JNI to instruct native code to allocate native memory, you need to use finalize to make sure it gets freed.
Late to the party here but thought I would still chime in:
One of the best uses I have found for finalizers is to call explicit termination methods which, for what ever reason, were not called. When this occurs, we also log the issue because it is a BUG!
Because:
There is no guarantee that finalizers will be executed promptly (or technically at all), per the language specification
Execution is largely dependent on the JVM implementation
Execution can sometimes be delayed if the GC has a lower thread priority
This leaves only a handful of tasks that they can address without much risk.
close external connections (db, socket etc)
close open files. may be even try to write some additional information.
logging
if this class runs external processes that should exist only while object exists you can try to kill them here.
But it is just a fallback that is used is "normal" mechanism did not work. Normal mechanism should be initiated explicitly.
Release resources that should be released manually in normal circumstances, but were not released for some reason. Perhaps with write a warning to the log.
I use it to write back data to a database when using soft references for caching database-backed objects.
I see one good use for finalize(): freeing resources that are available in large amounts and are not exclusive.
For example, by default there are 1024 file handles available for a Linux process and about 10000 for Windows. This is pretty much, so for most applications if you open a file, you don't have to call .close() (and use the ugly try...finally blocks), and you'll be OK - finally() will free it for you some time later. However for some pieces of code (like intensive server applications), releasing resources with .close() is a must, otherwise finally() may be called too late for you and you may run out of file handles.
The same technique is used by Swing - operating system resources for displaying windows and drawing aren't released by any .close() method, but just by finalize(), so you don't have to worry about all .close() or .dispose() methods like in SWT for example.
However, when there is very limited number of resources, or you must 'lock' resource to use it, also remember to 'unlock' it. For example if you create a file lock on a file, remember also to remove this lock, otherwise nobody else will be able to read or write this file and this can lead to deadlocks - then you can't rely on finalize() to remove this lock for you - you must do it manually at the right place.

Categories

Resources