2016-03-23 3 views
0

Я создал два метода тестирования, как показано ниже.Измерение размера объекта строки Java

private static long usedMem = 0; 
private static long newUsedMem = 0; 

public static long getSize() { 
    System.gc(); 
    usedMem = Runtime.getRuntime().totalMemory() 
      - Runtime.getRuntime().freeMemory(); 
    String s = "test"; 
    String y = "testabcd"; 

    System.gc(); 
    newUsedMem = Runtime.getRuntime().totalMemory() 
      - Runtime.getRuntime().freeMemory(); 

    return newUsedMem - usedMem; 
} 

public static long getSize2() { 
    System.gc(); 
    usedMem = Runtime.getRuntime().totalMemory() 
      - Runtime.getRuntime().freeMemory(); 
    String s = "test"; 
    String y = s+"abcd"; 

    System.gc(); 
    newUsedMem = Runtime.getRuntime().totalMemory() 
      - Runtime.getRuntime().freeMemory(); 

    return newUsedMem - usedMem; 
} 

Я ожидал, что оба метода должны обеспечить одинаковые результаты, поскольку они измеряют размеры строк x и String y. Тем не менее, первый метод постоянно возвращает 0, а второй метод постоянно возвращает 56 (я запускал каждый метод 10 раз в цикле, чтобы убедиться, что работает System.gc()). более

Одно замечание, что в первом способе, независимо от того, как долго строка s и у есть, результаты не всегда 0.

Может кто-нибудь объяснить различия мне?

+0

Я придумал тест, когда пытался использовать класс MemoryUtil и наблюдал некоторые расхождения. Это мой класс: 'public class Person { String firstName =" Alice "; Строка lastName = "Bob"; } '}' Я использовал измерение «MemoryUtil» и «run time» (аналогично тому, что я делал выше) для измерения размера объекта «Person», когда он инициализирован, но результаты не совпадают. –

ответ

2

Первый использует только строковые литералы, которые всегда присутствуют (загружаются загрузчиком классов во время инициализации класса), поэтому назначения не увеличивают память.

Второй по величине увеличивает память во втором присвоении по той же причине.

+0

После моего комментария к моему сообщению утилита 'MemoryUtil' возвращает значение, подобное методу' getSize2() 'для объекта' Person'. Означает ли это, что это неверно? Я получил «MemoryUtil» от http://www.javamex.com/classmexer/ –

+0

Чтобы сделать это более ясным; Компилятор вложил эти строки в программу, поэтому, пока программа выполняла назначение этих строк для переменных, не увеличивало объем памяти – dustinroepsch

+2

@HieuNguyen Я понятия не имею, что «MemoryUtil» делает внутри, или почему это имеет значение: и не я забота. Размер строкового литерала не является частью размера объекта. – EJP

0

При выполнении кучу конкатенации строк, компилятор Java преобразует молча

String a = b + c + d;

в

String a = new StringBuilder(b).append(c).append(d).toString();

Вот почему память будет увеличиваться во втором способе.

+0

Только если 'b, c, d' не являются окончательными или не имеют значения. – EJP

Смежные вопросы