I've spent a huge amount of time with Java. In fact, I regret not investigating other languages...
To cut it short, I really dislike how memory is managed and disposed of in Java. I have to be wary of what the garbage collector will pick up and dispose of, and what it won't. I'm writing server software for a project of mine, and on top of the multi-threading and synchronization, the memory management is difficult. I have to make sure I dispose of every reference to an object so the memory can be freed, which becomes more irritating as I progress through this sluggish project. I'm dealing with an extremely annoying bug: the main client object will not be disposed of after a connection is closed. I'm finding myself re-structuring my application so the all the references are removed, causing the object to be removed.
On top of my issues with Java, I need a native language.
But I hear in other languages you can dispose of memory manually. C# seems rather appealing, and it looks very similar to Java. C++ seems a lot different, and I don't know what are the pros and cons are regarding it. I'm debating on whether to choose C++ or C# right now. My big requirement is to be able to handle memory more directly.
I've done an enormous amount of work and study with Java, and I enjoy its syntax. I find myself comfortable creating large applications with Java, and I don't want a drastic change to my programming language that will leave me uncomfortable. Other programmers: what's a language that harnesses more power but isn't far from what the Java language is like?
C# has automatic garbage collection just as well as Java. You can invoke the garbage collector to collect, but that comes with other issues. I'm just getting into C/C++ and I feel a good amount of control over how memory is handle with these two languages.
Rollback Post to RevisionRollBack
NZXT Lexa S | | AMD Phenom II x3 B55 | | ASUS M4A79XTD Evo | | XFX Radeon 6870 | | Corsair VX 450W | | Kingston HyperX 8GB
I can't help but wonder if you're really in a situation that is a problem because of the language. Now I'm not a fan of Java, honestly, but, even if you switch to C++ I can almost guarentee you that most forums you pop on to ask this question they're going to suggest you use things like smart pointers. So what it comes down to is that people are going to try their best to shy you away from manual memory management, which makes me wonder if its really the garbage collector that is causing all your issues.
Of course you could try something like C++ if you really want which is completely unmanaged and unless you use soft management like smart pointers you literally will be calling delete on everything you allocate. But that might not necessarily 'fix" everything. Maybe you should just research into better ways of manipulating the garbage collector? C# isn't that different from Java in that regard really.. so. Switching languages may not alleviate problems.
the main client object will not be disposed of after a connection is closed.
If you do not call .close() on your end, the Object will not be finalized- and thus release the network socket- until it get's collected. I'm not sure why you are using the term "dispose" here. Sounds liek you want Deterministic Garbage Collection when what you really want is just deterministic clean-up.
I'm finding myself re-structuring my application so the all the references are removed, causing the object to be removed.
Objects that are still referenced cannot be cleaned up. Either set your socket objects to null- (defering actual clean-up to whenever the GC decides to run finalizers) or call .close() on the appropriate instances.... and then set them to null.
I need a native language.
No, you don't. You need a better understanding of the one you are using and the ability to realize that you cannot simply blame the technology when there are plenty of other people who don't have the problems you are doing the exact same things.
But I hear in other languages you can dispose of memory manually. C# seems rather appealing, and it looks very similar to Java.
C# uses the same stuff as Java in this regard. It adds some syntactic sugar that allows you to make sure an object is 'closed' properly, regardless of how a block is exited. Java currently requires the use of nested try...catch...finally blocks to do this.
C++ seems a lot different, and I don't know what are the pros and cons are regarding it. I'm debating on whether to choose C++ or C# right now. My big requirement is to be able to handle memory more directly.
Java and C# can only have memory leaks either because of the use of native code (java/s JNI or C#'s P/Invoke), or not cleaning up disposable objects that reference unmanaged resources, such as Files or Network streams. Most memory leaks occur because people go and cache these references in data structures; For example a class might add objects that are passed to one of it's methods in a member or static variable list structure. static member variables are a particular point of note, because they don't really have an enclosing scope and are essentially global; unless you set them to null, they will NEVER cleanup during the program run.
This may actually explain your situation. One common pattern for accepting connections is to keep them in a list of active connections. They get added. In your case, you could be assuming that sockets that you close yourself or that get closed remotely are magically cleaned up. But this is not the case; those instances stick around after they are closed and will stick around until the entire list is cleaned up- which will usually be after the program terminates. All those dead and zombie connections sit around with unmanaged resources and network handles (even a remotely closed socket has a valid network handle and structures for data transfer).
-Most event based systems will send a notification when a Socket is closed. use this to remove said socket from any active list. It won't be references and will be cleaned up. (alternately for a more deterministic approach, use .close() first).
-when you .close() a socket, remove it from the list. closeing it doesn't magically make the List know to remove the reference, so it sticks around.
I can't help but wonder if you're really in a situation that is a problem because of the language. Now I'm not a fan of Java, honestly, but, even if you switch to C++ I can almost guarentee you that most forums you pop on to ask this question they're going to suggest you use things like smart pointers. So what it comes down to is that people are going to try their best to shy you away from manual memory management, which makes me wonder if its really the garbage collector that is causing all your issues.
I agree with this. Most problems people have with the Garbage Collector is not understanding how it works at a basic level- particularly with regard to keeping live references, the mention of which in the OP I find... quizzical. The only difference between C++ and Java in this regard:
Java:
[code]Someunmanagedresourceobject=null;
//Object will have finalizer run at some arbitrary point in the future, cleaning up anything that object used.[/code]
C++:
[code]delete Someunmanagedresourceobject;
//Destructor will be called immediately, cleaning up any resources it used.[/code]
It doesn't really change anything- though it makes things deterministic. with Java and C# you generally use the appropriate cleanup method such as close; or for C#, most such objects implement IDisposable and have a .Dispose() method you should call before letting it go out of scope, otherwise any resources the instance uses will remain allocated until the object is finalized.
One point of note however is the difference between C++ stack local instances and local variables in Java and C#. For example:
[code]int somemethod()
{
StreamWriter sw = new StreamWriter("somefile.txt");
}[/code]
In the above case, fs will be cleaned up at some indeterminate time in the future; the reference is essentially cleared when they go out of scope, but the actual cleanup is up to the GC to do at some point. Calling this method twice in a row can result in a Permission Error since the file is already open in the limbo object that was instantiated in the previous call. Or, it could go perfectly fine, if the GC ran the finalizer in between.
the C++ equivalent. Note StreamWriter is not actually a C++ class but I'm far too lazy to look up the appropriate equivalent at the moment.
[/code]
[code]int somemethod()
{
StreamWriter sw("somefile.txt");
}[/code]
In this case, the instance will be cleaned up immediately when the method ends. Garbage Collection frees you from having to worry too much about manually allocating and deallocating objects and managing object lifetimes, but you trade in determinism. You can get it back, however:
[code]int somemethod()
{
StreamWriter sw = new StreamWriter("somefile.txt");
sw.Dispose();
}[/code]
(or using a using() block).
Note that manually allocated Objects (created with new and referenced via Pointers) can cause problems in C++ if you set the pointer to NULL without cleaning it up; which is sort of like setting a reference to null in C# or Java- but C++ doesn't magically clean up the data that pointer referenced. Then you have the issues of when you try to delete something more than once... or don't set a pointer to NULL and still think it's valid after cleaning it up, and so on. C++ Smart Pointers help alleviate these problems- by making them more automatic. You still have to write your code in a way to account for them, though. You can't go creating circular references or leaving references to objects around.
I'll try to educate myself more on handling these issues with garbage collection. I just never knew whether to try something different, or learn more about my current language. I had assumed I needed a native language because of the extra capabilities provided by them. Thanks for providing some insight on the differences between them.
My ideal feature in Java is to have a single method within the Object class which instructs the garbage collector to dispose of the object and sets all existing references to it as null. However, I could accomplish the same if I were to structure my applications out better, so that objects that do consume a large amount of memory lose all its references when need be.
No, you don't. You need a better understanding of the one you are using and the ability to realize that you cannot simply blame the technology when there are plenty of other people who don't have the problems you are doing the exact same things.
I'm not blaming the technology here, I'm questioning whether there's something better suited for me, and with what I'm doing, hence why I'm posting here. I've never gotten a taste in many languages before, so I don't know whether managing memory is easier in others than in Java.
This may actually explain your situation. One common pattern for accepting connections is to keep them in a list of active connections. They get added. In your case, you could be assuming that sockets that you close yourself or that get closed remotely are magically cleaned up. But this is not the case; those instances stick around after they are closed and will stick around until the entire list is cleaned up- which will usually be after the program terminates.
This is part of my situation. I was scrambling to remove references throughout the application to truly clean up the client instances...
-when you .close() a socket, remove it from the list. closeing it doesn't magically make the List know to remove the reference, so it sticks around.
Except the list isn't the only place in the application holding references to the socket. This is my issue, and I should be passing these references throughout the program, rather than creating entirely new ones.
Thanks for providing some education on the topic. I'll stay with Java and learn to work with its current garbage collector, and I'll be more aware when creating references to objects that are crucial to be removed and freed up. I think my huge issue in that project of mine is that I was being extremely messy with my references.
To cut it short, I really dislike how memory is managed and disposed of in Java. I have to be wary of what the garbage collector will pick up and dispose of, and what it won't. I'm writing server software for a project of mine, and on top of the multi-threading and synchronization, the memory management is difficult. I have to make sure I dispose of every reference to an object so the memory can be freed, which becomes more irritating as I progress through this sluggish project. I'm dealing with an extremely annoying bug: the main client object will not be disposed of after a connection is closed. I'm finding myself re-structuring my application so the all the references are removed, causing the object to be removed.
On top of my issues with Java, I need a native language.
But I hear in other languages you can dispose of memory manually. C# seems rather appealing, and it looks very similar to Java. C++ seems a lot different, and I don't know what are the pros and cons are regarding it. I'm debating on whether to choose C++ or C# right now. My big requirement is to be able to handle memory more directly.
I've done an enormous amount of work and study with Java, and I enjoy its syntax. I find myself comfortable creating large applications with Java, and I don't want a drastic change to my programming language that will leave me uncomfortable. Other programmers: what's a language that harnesses more power but isn't far from what the Java language is like?
EDIT: Crap, accidentally posted in the wrong section. Could this be moved to Software Discussion & Support ?
Of course you could try something like C++ if you really want which is completely unmanaged and unless you use soft management like smart pointers you literally will be calling delete on everything you allocate. But that might not necessarily 'fix" everything. Maybe you should just research into better ways of manipulating the garbage collector? C# isn't that different from Java in that regard really.. so. Switching languages may not alleviate problems.
If you do not call .close() on your end, the Object will not be finalized- and thus release the network socket- until it get's collected. I'm not sure why you are using the term "dispose" here. Sounds liek you want Deterministic Garbage Collection when what you really want is just deterministic clean-up.
Objects that are still referenced cannot be cleaned up. Either set your socket objects to null- (defering actual clean-up to whenever the GC decides to run finalizers) or call .close() on the appropriate instances.... and then set them to null.
No, you don't. You need a better understanding of the one you are using and the ability to realize that you cannot simply blame the technology when there are plenty of other people who don't have the problems you are doing the exact same things.
C# uses the same stuff as Java in this regard. It adds some syntactic sugar that allows you to make sure an object is 'closed' properly, regardless of how a block is exited. Java currently requires the use of nested try...catch...finally blocks to do this.
Java and C# can only have memory leaks either because of the use of native code (java/s JNI or C#'s P/Invoke), or not cleaning up disposable objects that reference unmanaged resources, such as Files or Network streams. Most memory leaks occur because people go and cache these references in data structures; For example a class might add objects that are passed to one of it's methods in a member or static variable list structure. static member variables are a particular point of note, because they don't really have an enclosing scope and are essentially global; unless you set them to null, they will NEVER cleanup during the program run.
This may actually explain your situation. One common pattern for accepting connections is to keep them in a list of active connections. They get added. In your case, you could be assuming that sockets that you close yourself or that get closed remotely are magically cleaned up. But this is not the case; those instances stick around after they are closed and will stick around until the entire list is cleaned up- which will usually be after the program terminates. All those dead and zombie connections sit around with unmanaged resources and network handles (even a remotely closed socket has a valid network handle and structures for data transfer).
-Most event based systems will send a notification when a Socket is closed. use this to remove said socket from any active list. It won't be references and will be cleaned up. (alternately for a more deterministic approach, use .close() first).
-when you .close() a socket, remove it from the list. closeing it doesn't magically make the List know to remove the reference, so it sticks around.
I agree with this. Most problems people have with the Garbage Collector is not understanding how it works at a basic level- particularly with regard to keeping live references, the mention of which in the OP I find... quizzical. The only difference between C++ and Java in this regard:
Java:
[code]Someunmanagedresourceobject=null; //Object will have finalizer run at some arbitrary point in the future, cleaning up anything that object used.[/code]
C++:
[code]delete Someunmanagedresourceobject; //Destructor will be called immediately, cleaning up any resources it used.[/code]
It doesn't really change anything- though it makes things deterministic. with Java and C# you generally use the appropriate cleanup method such as close; or for C#, most such objects implement IDisposable and have a .Dispose() method you should call before letting it go out of scope, otherwise any resources the instance uses will remain allocated until the object is finalized.
One point of note however is the difference between C++ stack local instances and local variables in Java and C#. For example:
[code]int somemethod() { StreamWriter sw = new StreamWriter("somefile.txt"); }[/code]
In the above case, fs will be cleaned up at some indeterminate time in the future; the reference is essentially cleared when they go out of scope, but the actual cleanup is up to the GC to do at some point. Calling this method twice in a row can result in a Permission Error since the file is already open in the limbo object that was instantiated in the previous call. Or, it could go perfectly fine, if the GC ran the finalizer in between.
the C++ equivalent. Note StreamWriter is not actually a C++ class but I'm far too lazy to look up the appropriate equivalent at the moment.
[/code]
[code]int somemethod() { StreamWriter sw("somefile.txt"); }[/code]
In this case, the instance will be cleaned up immediately when the method ends. Garbage Collection frees you from having to worry too much about manually allocating and deallocating objects and managing object lifetimes, but you trade in determinism. You can get it back, however:
[code]int somemethod() { StreamWriter sw = new StreamWriter("somefile.txt"); sw.Dispose(); }[/code]
(or using a using() block).
Note that manually allocated Objects (created with new and referenced via Pointers) can cause problems in C++ if you set the pointer to NULL without cleaning it up; which is sort of like setting a reference to null in C# or Java- but C++ doesn't magically clean up the data that pointer referenced. Then you have the issues of when you try to delete something more than once... or don't set a pointer to NULL and still think it's valid after cleaning it up, and so on. C++ Smart Pointers help alleviate these problems- by making them more automatic. You still have to write your code in a way to account for them, though. You can't go creating circular references or leaving references to objects around.
I'll try to educate myself more on handling these issues with garbage collection. I just never knew whether to try something different, or learn more about my current language. I had assumed I needed a native language because of the extra capabilities provided by them. Thanks for providing some insight on the differences between them.
My ideal feature in Java is to have a single method within the Object class which instructs the garbage collector to dispose of the object and sets all existing references to it as null. However, I could accomplish the same if I were to structure my applications out better, so that objects that do consume a large amount of memory lose all its references when need be.
I'm not blaming the technology here, I'm questioning whether there's something better suited for me, and with what I'm doing, hence why I'm posting here. I've never gotten a taste in many languages before, so I don't know whether managing memory is easier in others than in Java.
This is part of my situation. I was scrambling to remove references throughout the application to truly clean up the client instances...
Except the list isn't the only place in the application holding references to the socket. This is my issue, and I should be passing these references throughout the program, rather than creating entirely new ones.
Thanks for providing some education on the topic. I'll stay with Java and learn to work with its current garbage collector, and I'll be more aware when creating references to objects that are crucial to be removed and freed up. I think my huge issue in that project of mine is that I was being extremely messy with my references.
+1 for you.