问题
I know this may be a dumb question, but my background is more in c++ and managing my own memory.
I am currently cutting down every single allocation that I can from one of my games to try and reduce the frequency of garbage collection and perceived "lag", so for every variable that I create that is an Object (String and Rect for example) I am making sure that I create it before hand in my constructor and not create temporary variables in simple 10 line functions... (I hope that makes sense)
Anyways I was working though it some more tonight and I realized that I may be completely wrong about my assumption on garbage collection and primitive types (int, boolean, float) are these primitive type variables that I create in a 10 line function that gets called 20 times a second adding to my problem of garbage collection?
So a year ago every few seconds I would see a message in logcat like
GC freed 4010 objects / 484064 bytes in 101ms
Now I see that message every 15-90 seconds or so...
So to rephrase my question: Are primitive types (int, float, boolean, etc) included when seeing this message?
回答1:
Primitive types are not objects, so they do not cause any garbage collection. However, you do have to be very careful because due to boxing a primitive type can easily become an object without you explicitly doing so.
For example, if you want a HashMap<> of integer keys, you would use HashMap. Note that because "int" is not an object, it can't be used in a container. Integer is an object version of a primitive int. When you write code like this, an Integer object will automatically be created for you:
HashMap<Integer, Object> map = new HashMap<Integer, Object>();
int someNum = 12345; // no object created.
map.put(someNum, null); // Integer object created.
Note that the exact same thing will happen if you don't use generics, but even more hidden:
HashMap map = new HashMap();
int someNum = 12345; // no object created.
map.put(someNum, null); // Integer object created.
For this particular situation, you can use Android's SparseArray class, which is a container of primitive integer keys.
回答2:
It seems like the answer is no. It looks like primitives are put on the stack in Java and not in the heap and only objects are garbage collected. I found a lot of short references to this around, check Wikipedia. For some slightly heavier reading, see a paper on a JVM garbage collection implementation that explains a little more unambiguously that primitives are stored in physically separate memory locations so they are not mistakenly included in garbage collection here. If you feel like skimming, page 4 is where this is explained most directly.
here are android specific threads stating the gc only scans pointers and how it checks that
回答3:
[Note: I don't yet have full comment privileges, so I'm adding this as a separate answer.]
It looks like primitives are put on the stack in Java and not in the heap and only objects are garbage collected.
This is not quite accurate. Primitives can be held in local variables and also as the static or instance fields of classes. In the latter case, they are indeed stored on the heap, but they importantly do not have a "life" of their own and in particular aren't gc'ed separately from the object that they are contained within.
Android doesn't run a standard stack-based JVM, it has its own register based VM.
This is a true statement, but it's also a bit misleading and beside the point of the original question. In fact, when one method calls another (and so on), the activation frames of these methods are stored on a stack in the Dalvik implementation. The difference is that, when looking at an activation frame in isolation, Dalvik activation frames don't contain within them a variable-size stack. In this regard, the way Dalvik arranges activation frames is more like how they are handled for traditional C-like languages (such as C or C++).
来源:https://stackoverflow.com/questions/2474622/are-primitive-types-garbage-collected-in-android