3 ms·
I wish I could say the same. Most times it ended up one of two ways: Either the app is stuck doing GC, or it crashes with OutOfMemoryError: too many this or tha
by oriolid 5y ago
I wish I could say the same. Most times it ended up one of two ways: Either the app is stuck doing GC, or it crashes with OutOfMemoryError: too many this or that handles, open pipes or something else.
- Tainnor 5y agoI don't know what kinds of things you're doing on the JVM, but the only situations where I've seen these kinds of errors were either a) batch jobs on massive amounts of data (which yeah... it figures that they could OOM, not sure how you'd prevent that), or b) a serious error in application logic. In general, I don't really encounter these problems and neither do most other people who write for the JVM.
- pjmlp 5y agoSame here, usually you get that from code that uses new everywhere without any kind of thought regarding proper use of algorithms and data structures.
- smrtinsert 5y agoYou have to work very poorly to get these types of errors.
- cogman10 5y ago> too many this or that handles, open pipes or something else. I'm sorry, but that sort of message is a pretty strong indicator of programmer error. Are you using try-with-resources to properly close out things? Are you creating threads in an unbounded fashion? (new Thread) Are you keeping references to objects for longer than needs be? Have you used Java flight recorder to identify the root cause of you memory pressure or used eclipse MAT to find large long lubed allocations? (Or both?). Are you using finalizes? Those have been STRONGLY discouraged (and for good reason) for decades now.
- oriolid 5y agoNo. I am the poor programmer whose manager forced me to use a library their nephew's dog or someone wrote that does all of those. Except using finalize for closing pipes for subprocesses, that was by Java standard library itself. And keeping references longer than needed, that is every library that implements clever caching, ever. Regarding try-with-resources, RAII was invented for a reason. Java did not copy it, because they seemed to seriously believe that GC is a good substitute. One of the many features of Java is that it is advertised as being easy enough that any idiot can write it, and managers then hire idiots.
- vips7L 5y agoHow do you expect RAII to work in any GC language? It would be non-deterministic. The point of try-with-resources is that it is deterministic and you know when something is closed out. Every GC language has implemented this.
- oriolid 5y agoI would say that RAII is enforced try-with-resources without the extra syntax and releasing memory when resources are released instead of having a garbage collector is a nice performance optimization. C# with "using var" is on the right track, though. Just make RAII default and explicit close/dispose the special case and add syntax for type-deduced immutable values, and I'd be happy.
- cogman10 5y ago> No. I am the poor programmer whose manager forced me to use a library their nephew's dog or someone wrote that does all of those My condolences, that sucks. I'd still suggest using the profiling tools I've suggested to find these issues and create change requests to said libs. People will think you're a wizard if you simply learn how to use Java's telemetry. It's an invaluable skill. > Except using finalize for closing pipes for subprocesses, that was by Java standard library itself Java uses finalizers as a last resort, not a first line. Finalizers are due to be removed from the language so don't count on them being around for long. > And keeping references longer than needed, that is every library that implements clever caching, ever. Sure, caching is legitimate when the cost of creating exceeds the cost of long lived objects. Have you measured to see if the caches you have are improperly sized? Have you made pull requests/change requests to said libraries to fix it if it is? > Regarding try-with-resources, RAII was invented for a reason. Java did not copy it, because they seemed to seriously believe that GC is a good substitute. RAII was, few languages have it. The languages that don't have it generally don't have it because tracking the lifetime of objects in a GCed language can be extremely difficult. Consider, for example, how java would handle a destructor for an object allocated in one thread shared with multiple other threads. Do you know how C++/Rust/D solve that problem? Through a system of reference counted smart pointers which have to be handled very delicately. Java allows such objects to be freely moved. There are pros and cons to GCs (like most language features) so instead of just defaulting to "man, GCed languages suck because the finalizers aren't called when I want them to be!" perhaps it's a better route to learn the idiomatic way of handling resources and use that?