Java is only a "Hog for RAM" if you write code for that hogging.
Old school Java had not "concurrent garbage collection".
So it literally ran until the memory was used up, and the moment you called "new Object()" the memory allocator said: oops we are out of memory.
As multithreaded clean up is not trivial (at that time, because no one really knew how to do it), the VM stopped all threads, reclaimed unused memory and did the so called "stop the world garbage collection".
In our times, we have concurrent multi threaded - generational - compacting - garbage collection. Which is in general: faster than malloc()/free() in C. At least for most stdc libraries that are coming with a typical compiler distribution.
Then again, in C times we did read text files line by line. Perhaps into a 700byte buffer that could hold two disk sectors or one block from a hard drive.
Now slurp in a whole file. Then call "split(text, '\n')" to get an array of lines: because we have the memory for the whole file, and the memory for all the lines ...
Has nothing to do with Java or with (insert other perceived memory hungry language) - it is a matter how you program.
I can re-write you every C program in Java, and it does not need more RAM than your C version. Of course, it would be "annoying" if you force me to use bytes where you used chars.
And except for the start up time of the JVM, and if it runs long enough the JIT compiling: it will have the same speed as C.