GabrielBailey74
|
 |
«
Posted
2013-01-25 04:01:16 » |
|
I've had this method lying around for a few months now  Might not be a smart idea, but I've implemented this to run every few seconds. The only noticeable difference is a 70FPS to 67FPS drop when it manages to clean something forcefully, and it reports back the megabyte's of allocated memory cleaned. (No need for pixel arrays / objects to be floating around, once they're no longer needed execute this method and they'll hit the road running, leaving you with some memory cleaned  ) Method: 1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19
| public static void fullGC() { final long MB = 1024; final Runtime rt = Runtime.getRuntime(); long isFree = rt.freeMemory(); long wasFree; do { wasFree = isFree; rt.gc(); isFree = rt.freeMemory(); } while (isFree > wasFree); rt.runFinalization(); if (wasFree > isFree) { final long mbCleaned = Math.abs((isFree / MB / MB) - (wasFree / MB / MB)); if (mbCleaned > 0) { System.out.println("Managed to clean: "+mbCleaned+"mb."); } } } |
Output: 1 2 3 4 5 6 7
| Display Created. (User re-sizes screen, pixel data increases) (User restores screen to normal size, extra pixel data now floating around) Managed to clean: 1mb. Managed to clean: 2mb. Managed to clean: 2mb. Display Disposed. |
Hope somebody finds this helpful, I'm use to hearing posts like "No, there's no way to forcefully garbage collect..". 
|
|
|
|
davedes
|
 |
«
Reply #1 - Posted
2013-01-25 04:26:02 » |
|
This sounds like a really, really terrible idea.
Serious WTF... System.gc() can cause "stop-the-world" garbage collection; doing it multiple times within a loop (let alone frequently within the game loop) might seriously affect performance and lead to a lot of stuttering/bugs.
General rule of thumb for desktop: as long as you aren't doing anything stupid (like loading an image every frame), then you shouldn't need to worry about GC and memory.
|
|
|
|
ClickerMonkey
|
 |
«
Reply #2 - Posted
2013-01-25 04:28:04 » |
|
This sounds like a really, really terrible idea.
Serious WTF... System.gc() can cause "stop-the-world" garbage collection; doing it multiple times within a loop (let alone frequently within the game loop) might seriously affect performance and lead to a lot of stuttering/bugs.
General rule of thumb for desktop: as long as you aren't doing anything stupid (like loading an image every frame), then you shouldn't need to worry about GC and memory.
Couldn't agree more, and this isn't his opinion, it's FACT.
|
|
|
|
Games published by our own members! Check 'em out!
|
|
GabrielBailey74
|
 |
«
Reply #3 - Posted
2013-01-25 04:28:39 » |
|
This sounds like a really, really terrible idea.
Serious WTF... System.gc() can cause "stop-the-world" garbage collection; doing it multiple times within a loop (let alone frequently within the game loop) might seriously affect performance and lead to a lot of stuttering/bugs.
General rule of thumb for desktop: as long as you aren't doing anything stupid (like loading an image every frame), then you shouldn't need to worry about GC and memory.
If you're the type of person who program's a application and likes to just leave nulled / unused objects lying around consuming allocated memory sure, don't worry about cleaning.. I on the other hand i do need all the memory free that I can use. EDIT: Sorry I just ran over a method I haven't seen in a while that contradicts a thousand statements saying "NO YOU CAN'T FORCE GC" and decided to post it on here :L
|
|
|
|
ClickerMonkey
|
 |
«
Reply #4 - Posted
2013-01-25 04:31:19 » |
|
This sounds like a really, really terrible idea.
Serious WTF... System.gc() can cause "stop-the-world" garbage collection; doing it multiple times within a loop (let alone frequently within the game loop) might seriously affect performance and lead to a lot of stuttering/bugs.
General rule of thumb for desktop: as long as you aren't doing anything stupid (like loading an image every frame), then you shouldn't need to worry about GC and memory.
If you're the type of person who program's a application and likes to just leave nulled / unused objects lying around consuming allocated memory sure, don't worry about cleaning.. EDIT: Sorry I just ran over a method I haven't seen in a while that contradicts a thousand statements saying "NO YOU CAN'T FORCE GC" and decided to post it on here :L Yeah, their haters. Your method is brute force, it doesn't stop the loop until SOMETHING is cleaned up.. so of course it won't return until something is cleaned up!
|
|
|
|
sproingie
|
 |
«
Reply #5 - Posted
2013-01-25 04:33:08 » |
|
This isn't "forcefully" doing jack, it's waiting til gc eventually kicks in at some point and noticing the heap shrinking. If another thread does allocations, this one might never return. Now it's true that Runtime.gc() will push a full gc well ahead of schedule (it's what that little trash icon in eclipse calls) and I should mention again full gc. Thus defeating the purpose of a generational collector in the first place.
Basically this is just terrible advice, and anyone who actually knows enough to know when to call for full gc legitimately isn't going to follow this nonsensical pattern.
|
|
|
|
|
GabrielBailey74
|
 |
«
Reply #6 - Posted
2013-01-25 04:36:03 » |
|
This isn't "forcefully" doing jack, it's waiting til gc eventually kicks in at some point and noticing the heap shrinking. If another thread does allocations, this one might never return. Now it's true that Runtime.gc() will push a full gc well ahead of schedule (it's what that little trash icon in eclipse calls) and I should mention again full gc. Thus defeating the purpose of a generational collector in the first place.
Basically this is just terrible advice, and anyone who actually knows enough to know when to call for full gc legitimately isn't going to follow this nonsensical pattern.
lmao..  If I see a program in front of me that's using 25MB of memory when it clearly only should be using 9MB (Just a example), if I can forcefully call 'Garbage Collection' when I choose too and get rid of unused / nulled objects lying around accumulating unnecessary space, of course I will. (Knocking it back down to 9MB)
|
|
|
|
sproingie
|
 |
«
Reply #7 - Posted
2013-01-25 04:37:43 » |
|
"lmao" indeed. So basically either I've been trolled or you really are just being deliberately ignorant. Good show.
|
|
|
|
|
GabrielBailey74
|
 |
«
Reply #8 - Posted
2013-01-25 04:41:42 » |
|
Like I said..
If you're the type of person who program's a application and likes to just leave nulled / unused objects lying around consuming allocated memory sure, don't worry about cleaning..
If I can perform this with only 1 side effect being a '3 FPS' drop on occasion.. why not? :L
I'm the stupid one for doing more than your average programmer and optimizing memory? lolz, mk skip.
EDIT: XD now your post says 'deliberately ignorant'.
|
|
|
|
davedes
|
 |
«
Reply #9 - Posted
2013-01-25 04:45:45 » |
|
I'm the stupid one for doing more than your average programmer and optimizing memory? ... 
|
|
|
|
Games published by our own members! Check 'em out!
|
|
GabrielBailey74
|
 |
«
Reply #10 - Posted
2013-01-25 04:49:53 » |
|
It's all good, hop off this thread if you don't like it / don't find it useful, don't criticize me and literally call me stupid ROFL. Pretty sure there's some people out there who have browsed for this type of method and have found nothing but people saying "Nope, can't force GC you can only 'recommend it'..". 15ms - 62ms elapsed for cleaning 4MB of memory, really a 'studder / bug causer' ey..  
|
|
|
|
ra4king
|
 |
«
Reply #11 - Posted
2013-01-25 05:09:51 » |
|
"lmao" indeed. So basically either I've been trolled or you really are just being deliberately ignorant. Good show.
Guys....I think he literally can't see what he's doing wrong....... Gabriel, I'm quite used to hearing you lash out about how "we're all wrong and you're right". In fact, with a bit of digging, I can find that thread where you called me out for "criticizing everything you do". However, this time, *please* listen to us. This is useless. This does nothing. The GC will run on its own optimized time when the system/app/whatever needs the memory. Forcing it like this will do absolutely nothing other than make your application stutter and glitchy, not to mention that you still use Java2D, making matters worse. Coupled with the side effects the others mentioned, plus the bug on line 13, this is a terrible idea and terrible advice. Take this not as insults, but as helpful and useful criticism!
|
|
|
|
davedes
|
 |
«
Reply #12 - Posted
2013-01-25 05:18:35 » |
|
It's great that you are trying to help newbies by posting shared code; but you need to learn to take criticism. In this case, your code is utterly nonsensical and downright stupid. By suggesting this to newbies you are only encouraging bad programming practices and buggy code.
Your method doesn't "force" GC. It only recommends it, and waits until GC has cleaned up some memory. Since System.gc isn't guaranteed to do anything, your code is pretty much just an empty loop that blocks the game until memory is freed up at some point. There is no telling how long this wait may be, as it's JVM dependent.
Further; if you are really concerned about a few extra bytes of memory, you shouldn't be using Swing/AWT in the first place.
|
|
|
|
GabrielBailey74
|
 |
«
Reply #13 - Posted
2013-01-25 05:23:03 » |
|
Your method doesn't "force" GC. It only recommends it.
That's funny, why don't you go program a application that shows some live memory statistics.  Go accumulate some memory, see how long it takes to get cleaned.  If you DO program a application that shows some live memory statistics, after you invoke this method you WILL see that the allocated memory has in fact 'Deceased'. So for you to say 'This method doesn't "Force" GC, it only recommends' it is false, you're just saying what the other 10,000 people have said :L
|
|
|
|
ra4king
|
 |
«
Reply #14 - Posted
2013-01-25 05:24:04 » |
|
Aaaaand you've finally proved your ignorance and newbiness. I give up with you Gabriel. Have a good day!
It is pointless to keep responding to him guys. He doesn't read nor does he understand.
|
|
|
|
GabrielBailey74
|
 |
«
Reply #15 - Posted
2013-01-25 05:25:22 » |
|
Aaaaand you've finally proved your ignorance and newbiness. I give up with you Gabriel. Have a good day!
It is pointless to keep responding to him guys. He doesn't read nor does he understand.
I'm not going to argue with a 12 14 year old lol.  *gasp* never mind, guess he's apparently 17 now. 1. I didn't lash out, I said you were following most of rivens remarks up when they were aimed @ me but W.E. 2. I never said or hinted 'My works correct, all JGO's is wrong'. 
|
|
|
|
ReBirth
|
 |
«
Reply #16 - Posted
2013-01-25 05:31:29 » |
|
Hey all let's cool  off-topic: ra4king is the only 14 yo Homo Sp who I don't want to mess up with in term of Java 
|
|
|
|
|
|
GabrielBailey74
|
 |
«
Reply #18 - Posted
2013-01-25 05:40:25 » |
|
Thanks mate. Googled: while (isFree > wasFree) and found out where I got that method from: http://www.j2eeonline.com/advanced-java-oop/module1/forcing-garbage-collection.jspThought it was a code snippet worth posting, W.E guess not. I'll delete it tomorrow if no one finds it helpful. Thanks for all the reply's,  apparently ra4king's still butt hurt, pops up out of no where having not said a word to me in weeks/months with some ass backwards info.
|
|
|
|
sproingie
|
 |
«
Reply #19 - Posted
2013-01-25 05:46:32 » |
|
EDIT: XD now your post says 'deliberately ignorant'.
Yes, I edited out "stupid". Now I realize I shouldn't have. In fact I have even stronger things to say but you are the furthest thing from being worth the effort.
|
|
|
|
|
Riven
|
 |
«
Reply #20 - Posted
2013-01-25 08:15:22 » |
|
I've had this method lying around for a few months now  Might not be a smart idea, but ... In you opening post you seemed to be open to critique. When everybody around you says you made an obvious mistake, you're either a genius or need to pay attention really quick.
|
|
|
|
GabrielBailey74
|
 |
«
Reply #21 - Posted
2013-01-25 08:34:54 » |
|
LAWL, I didn't make a mistake, this is a shared code snippet. This method does exactly what the title says, you call it memory gets cleaned. I built a application to monitor the allocated memory, there was no program blockage. THIRD TIME: Everywhere I've looked for methods on forcefully invoking garbage collection yield back the same result....... "No, you cannot forcefully call GC, you can only suggest it." This snippet is the opposite of it, somebody will make use of it / find it helpful, regardless of the 15ms delay.  Feel like I'm on a forum with a bunch of blind people.    Anyways, thanks for the tips all. 
|
|
|
|
ReBirth
|
 |
«
Reply #22 - Posted
2013-01-25 08:50:03 » |
|
Thanks to Mario and crew, I stay foolish enough to worry about memory or even delta but content only. 
|
|
|
|
Riven
|
 |
«
Reply #23 - Posted
2013-01-25 09:03:05 » |
|
There are six flaws: (apart from flaws already mentioned by others) 1. if the jvm manages to shrink the heap, the free space might have reduced, after a GC. 2. you will trigger full-GCs, which use a stop-the-world approach. 3. continuously forcing the GC takes much more cpu time than letting the jvm determine the best time to run it. 4. 70fps vs, 67fps might seem like a reasonable tradeoff, but you just froze the game for 40-50ms, which is noticable. Even a single framedrop at 60Hz can be noticed. 5. in gaming, we happily trade memory usage for cpu cycles to keep framerate consistent. 6. your method doesn't really solve a problem, unless your OS is running out of RAM.
|
|
|
|
GabrielBailey74
|
 |
«
Reply #24 - Posted
2013-01-25 09:08:13 » |
|
There are six flaws: (apart from flaws already mentioned by others) 1. if the jvm manages to shrink the heap, the free space might have reduced, after a GC. 2. you will trigger full-GCs, which use a stop-the-world approach. 3. continuously forcing the GC takes much more cpu time than letting the jvm determine the best time to run it. 4. 70fps vs, 67fps might seem like a reasonable tradeoff, but you just froze the game for 40-50ms, which is noticable. Even a single framedrop at 60Hz can be noticed. 5. in gaming, we happily trade memory usage for cpu cycles to keep framerate consistent. 6. your method doesn't really solve a problem, unless your OS is running out of RAM.
Thank you, duly noted. (Probably why riven added #6 D:) I'm sorry guys, I forgot to mention my computers a dinosaur... (I need RAM) So I tend to over compensate in memory areas I guess? 
|
|
|
|
Riven
|
 |
«
Reply #25 - Posted
2013-01-25 09:10:37 » |
|
Adding to that: 1. since when is an MB equal to 1024? 2. why did you use Math.abs(...) when calculating the amount of memory freed?
|
|
|
|
Riven
|
 |
«
Reply #26 - Posted
2013-01-25 09:15:47 » |
|
I'm sorry guys, I forgot to mention my computers a dinosaur... (I need RAM)
You can buy RAM for cheap. I can't look in your wallet, but you may want to spend $10 on some second hand memory bank.
|
|
|
|
Roquen
|
 |
«
Reply #27 - Posted
2013-01-25 10:18:16 » |
|
I don't think this has been explicitly stated: on desktop/server hardware...virtual memory is pretty cheap and not something to think about unless you're getting into a significant percentage of your physical memory.
And if you really what to play with how HotSpot does it's GC thing...then way to go is through the literally hundreds of command line options.
|
|
|
|
|
ReBirth
|
 |
«
Reply #28 - Posted
2013-01-25 10:23:18 » |
|
I don't know what you want to do, but considering my level I was gladly to use 1GHz 384MB memory machine which forced me to use JCreator rather Eclipse up to 1 years ago. Without wonderful features, I learned lot things about Java. Sometime limitation could bring gift.
In your case, machine limit brought you to think up a solution for memory optimization. You came up with one, posted it, and received lot of good advices.
|
|
|
|
theagentd
|
 |
«
Reply #29 - Posted
2013-01-25 11:50:10 » |
|
A 50ms delay is completely unacceptable. It's very easy to spot such a hickup and ruins any game even remotely based on timing (= all realtime games).
I think you've misunderstood 2 things.
First, using less memory doesn't give more performance. It simply uses less memory, which if you have a veeery low amount of RAM is a good thing of course. However, if I remember correctly the VM cannot allocate more memory than is actually available, so as long as the program starts your computer won't run out of memory (unless you also start something heavy in the background after).
Secondly, it's impossible to get an out-of-memory error due to too much garbage. When you finally get an OutOfMemoryError, garbage collection will have already been run and the heap is actually 100% clean and filled with live objects.
Those two together should be enough to almost never make you manually call gc(), especially not in a time critical program like a game each frame. To be 100% honest, I do actually call gc() once in my code. I have a super-inefficient world loading method in one of my projects which sometimes allocates several gigabytes of shortlived data. The GC takes care of this perfectly well and there's no significant performance loss there. After loading I SUGGEST that the GC should run a garbage collection to remove any remaining garbage after loading with gc(). That's to prevent a large GC pause after the level starts to clean up the loading garbage.
|
Myomyomyo.
|
|
|
|