Java - inline initialized string array memory allocation on heap?

六月ゝ 毕业季﹏ 提交于 2019-12-10 11:30:59

问题


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

易学教程内所有资源均来自网络或用户发布的内容,如有违反法律规定的内容欢迎反馈
该文章没有解决你所遇到的问题?点击提问,说说你的问题,让更多的人一起探讨吧!