For those of you that do not what JCIFS is, it is a Java library which helps you deal with SMB Files in a way very similar to handling normal local File objects. You can list files, open input streams, delete, rename and some other operations.
Recently I was working with this library, specifically building small search tool, which crawls the directories you specify and then return the results. Apparently I was having problems with something that many people tend to overlook, or forget about. Handles originating from my java program never seemed to close.
As you can see, many applications have a few hundreds, including the JVM I have running (see screenshot). So the other day I was testing memory and CPU usage, and they were pretty much under control, until I had a look at the handles column. I began testing small directories, containing less than 30 or so items in total. The handle count rose but it was negligible, since it was at maybe 50 and maybe rose to seventy something. I did not notice since a number of handles might be opened by the JVM and not my code so I ignored it.
After the initial tests, I thought some heavier directory should be crawled, so I pointed it to the desktop, which contains thousands of files (within sub directories obviously, not even a 100" TV could have a 1000 icons on the desktop :P). So again, I fired up the program and bam! I had over 15000 handles, which is absolutely unacceptable.
Practically I have found no solution to this, yet. I really would like to know if any one has had this problem, because as far as I know, there are no methods that close the connection. You can only close streams, and that's OK, but what should I close if I am calling list() or listFiles()?
Showing posts with label garbage collector. Show all posts
Showing posts with label garbage collector. Show all posts
07 December, 2011
06 December, 2011
Crashing the JVM
The Java Virtual Machine is quite impressive, considering it is so stable that large corporations and even banks depend on it to perform a myriad of tasks. Even Google uses it. So there you go, a great tool which is stable, clean, fast and loved by many.
As you might also know, it works by having byte code being sort of interpreted and executed, in real time. Now the problems lies not in this relatively intense part of the system, but at a higher level - the language itself. You see, Java makes it easy to create, use and handle objects, but how the hell can you create an object without ever reserving memory for it, just like in C++, for instance. Java does this automatically, and it also destroys and gives back memory (to the OS) automatically.
That task belongs to the garbage collector, a separate thread running in the background, and then at some point, stops everything (really, it's called "Stopping the world") and removes any unused objects laying around. Basically what can happen is that if the memory is not being cleaned, you end up putting every single new byte in memory, on the heap. The memory is obviously limited, so eventually it will crash. This can be caught by "OutOfMemoryError", as you would usually catch normal exceptions. It is not always possible though, since when the JVM crashes, the problem is "outside" of the program execution, specifically in the memory manager. Segmentation fault, as it is known, happens when the memory can't be managed.
The following code causes this error, and the reason is that we are creating an array of the same array, which eventually adds up to one huge array of array of array of etc. This basically crashes the whole JVM and will give you a JVM error, which unlike traditional errors, can't be handled.
So essentially, the moral of the story is that even though it is clean and simpler to leave GC out, please, always ensure that you still keep object creation under control, as you do not really know what happens during execution. It is also important to keep that in mind when coding mobile apps, those devices have much less memory, and processing power for that matter. Please also note that this code is common on the internet so it is easy to find it (and more crashing code) also in fora and other blogs...
As you might also know, it works by having byte code being sort of interpreted and executed, in real time. Now the problems lies not in this relatively intense part of the system, but at a higher level - the language itself. You see, Java makes it easy to create, use and handle objects, but how the hell can you create an object without ever reserving memory for it, just like in C++, for instance. Java does this automatically, and it also destroys and gives back memory (to the OS) automatically.
![]() |
| Don't put this kind of code if your building some arsenal management console. Really, don't. |
That task belongs to the garbage collector, a separate thread running in the background, and then at some point, stops everything (really, it's called "Stopping the world") and removes any unused objects laying around. Basically what can happen is that if the memory is not being cleaned, you end up putting every single new byte in memory, on the heap. The memory is obviously limited, so eventually it will crash. This can be caught by "OutOfMemoryError", as you would usually catch normal exceptions. It is not always possible though, since when the JVM crashes, the problem is "outside" of the program execution, specifically in the memory manager. Segmentation fault, as it is known, happens when the memory can't be managed.
The following code causes this error, and the reason is that we are creating an array of the same array, which eventually adds up to one huge array of array of array of etc. This basically crashes the whole JVM and will give you a JVM error, which unlike traditional errors, can't be handled.
So essentially, the moral of the story is that even though it is clean and simpler to leave GC out, please, always ensure that you still keep object creation under control, as you do not really know what happens during execution. It is also important to keep that in mind when coding mobile apps, those devices have much less memory, and processing power for that matter. Please also note that this code is common on the internet so it is easy to find it (and more crashing code) also in fora and other blogs...
Object[] o = null;
while (true)
o = new Object[]{ o };
while (true)
o = new Object[]{ o };
Subscribe to:
Posts (Atom)


