问题
String[] stringArray = new String[] { "abc", "xyz" };
Executing this line there are two String literals created "abc" and "xyz" in PERMGEN space. Since the initialization has a new operator I am not sure if there's any memory allocated on HEAP.
Thanks guys.
回答1:
All objects, except string literals, are created on the heap. From Java 7, string literals are created on the heap as well.
In theory, escape analysis can prevent new
object from being created on the heap and perhaps using the stack instead. This rarely happens in practice AFAIK.
In answer to EJP question, I haven't fund a non trivial example but
From http://www.oracle.com/technetwork/server-storage/ts-7392-159315.pdf page 22
New Technology: Escape Analysis
Definition: An object escapes the thread that allocated it if
some other thread can ever see it
If an object doesn't escape, we can abuse it
• Object explosion: allocate object's fields in different places
• Scalar replacement: store scalar fields in registers
• Thread stack allocation: store fields in stack frame
• Eliminate synchronization
• Eliminate initial object zero'ing
• Eliminate GC read / write barriers
Enabled with -XX:+DoEscapeAnalysis in JDKTM version 6
In theory this feature has been there for some time, but it didn't work particularly often (even find a contrived example was hard) In Java 7, finding contrived examples is easier. ;)
public class UsesWrappersMain {
public static void main(String... args) {
for (int j = 0; j < 10; j++) {
long used = used(), count = 0;
for (int i = 0; i < 2000; i++) {
count += printSum();
}
// add an object to show it is working
byte[] b = new byte[16];
long used2 = used();
System.out.printf("Memory used for %,d iterations was %,d bytes%n", count, used2 - used);
}
}
private static int printSum() {
int count = 0;
for (float i = 0; i < 10000; i++) {
// definitively not autoboxed.
Float j = new Float(i);
count++;
}
return count;
}
private static long used() {
return Runtime.getRuntime().totalMemory() - Runtime.getRuntime().freeMemory();
}
}
prints when run with -XX:-UseTLAB
Memory used for 20,000,000 iterations was 480,888 bytes
Memory used for 20,000,000 iterations was 32 bytes
Memory used for 20,000,000 iterations was 32 bytes
Memory used for 20,000,000 iterations was 32 bytes
Memory used for 20,000,000 iterations was 32 bytes
Memory used for 20,000,000 iterations was 32 bytes
Memory used for 20,000,000 iterations was 32 bytes
Memory used for 20,000,000 iterations was 0 bytes
Memory used for 20,000,000 iterations was 0 bytes
Memory used for 20,000,000 iterations was 0 bytes
if you add -XX:-DoEscapeAnalysis
which is not the default
Memory used for 20,000,000 iterations was 320,000,928 bytes
Memory used for 20,000,000 iterations was 320,000,032 bytes
Memory used for 20,000,000 iterations was 320,000,032 bytes
Memory used for 20,000,000 iterations was 320,000,032 bytes
Memory used for 20,000,000 iterations was 320,000,032 bytes
Memory used for 20,000,000 iterations was 320,000,032 bytes
Memory used for 20,000,000 iterations was 320,000,032 bytes
Memory used for 20,000,000 iterations was 320,000,144 bytes
Memory used for 20,000,000 iterations was 320,000,032 bytes
Memory used for 20,000,000 iterations was 320,000,032 bytes
回答2:
What happens when you execute this is that you will get:
- Two string literals in permgen
- Two String objects in the heap
- One String-array object in the heap
Even though the actual literal strings are kept in the String pool in permgen, String-objects are still stored in the heap.
来源:https://stackoverflow.com/questions/12822413/java-inline-initialized-string-array-memory-allocation-on-heap