|
|
|
Экономно расходование памяти
|
|||
|---|---|---|---|
|
#18+
Подскажите приемы для экономного расходования-снижения памяти, используемой приложением. По этой теме не так много материала. Иногда встречаются такие советы: Случай 1, вместо этого: Код: java 1. 2. 3. делают так: Код: java 1. 2. 3. 4. Случай 2: передавая в метод объект класса, перед выходом из метода, делают: Код: java 1. Случай 3: Предлагают использовать Trove library для коллекций, насколько это актуально? ... |
|||
|
:
Нравится:
Не нравится:
|
|||
| 10.06.2014, 12:32 |
|
||
|
Экономно расходование памяти
|
|||
|---|---|---|---|
|
#18+
rema174Подскажите приемы для экономного расходования-снижения памяти, используемой приложением. Java Memory Profiler - самый важный приём. Превентивные оптимизации - зло. rema174Случай 1, вместо этого: Код: java 1. 2. 3. делают так: Код: java 1. 2. 3. 4. Ерунда. Разве что речь о какой-то экстравагантной Java вроде J2ME. И то не факт что там такое нужно. rema174Случай 2: передавая в метод объект класса, перед выходом из метода, делают: Код: java 1. Для аргумента? Ну, бред же. rema174Предлагают использовать Trove library для коллекций, насколько это актуально? Ну, актуально иногда. Если у вас большие массивы примитивов, то использованеи оберток повлечет за собой дополнительные расходы по памяти. Тогда можно взять коллекции созданые для примитивов. Почему нет? Или, например, от String отказаться в пользу char[] или даже byte[]. Тоже имеет смысл в качестве оптимизации, а не в качетсве практики. ... |
|||
|
:
Нравится:
Не нравится:
|
|||
| 10.06.2014, 12:41 |
|
||
|
Экономно расходование памяти
|
|||
|---|---|---|---|
|
#18+
Blazkowicz, насчет первых двух случаев согласен, ерунда ... |
|||
|
:
Нравится:
Не нравится:
|
|||
| 10.06.2014, 12:56 |
|
||
|
Экономно расходование памяти
|
|||
|---|---|---|---|
|
#18+
Все не было повода спросить. Тут вроде подходящее место. А как насчет декларации аргументов final? Встречал в одном проекте обязательность такого. Аргумент -- для увеличения производительности. Сомнения загнал подальше, но они остались. ... |
|||
|
:
Нравится:
Не нравится:
|
|||
| 10.06.2014, 16:27 |
|
||
|
Экономно расходование памяти
|
|||
|---|---|---|---|
|
#18+
Alexander A. SakВсе не было повода спросить. Тут вроде подходящее место. А как насчет декларации аргументов final? Встречал в одном проекте обязательность такого. Аргумент -- для увеличения производительности. Сомнения загнал подальше, но они остались. Скомпилируйте класс с final аргументами в методах и убедитесь что байткод не отличается. ... |
|||
|
:
Нравится:
Не нравится:
|
|||
| 10.06.2014, 16:44 |
|
||
|
Экономно расходование памяти
|
|||
|---|---|---|---|
|
#18+
BlazkowiczСкомпилируйте класс с final аргументами в методах и убедитесь что байткод не отличается. Хотя, в Java 8 в метаинформации класса теперь хранятся и "параметры". Но байт-код метода не должен отличаться. ... |
|||
|
:
Нравится:
Не нравится:
|
|||
| 10.06.2014, 16:48 |
|
||
|
Экономно расходование памяти
|
|||
|---|---|---|---|
|
#18+
BlazkowiczAlexander A. SakВсе не было повода спросить. Тут вроде подходящее место. А как насчет декларации аргументов final? Встречал в одном проекте обязательность такого. Аргумент -- для увеличения производительности. Сомнения загнал подальше, но они остались. Скомпилируйте класс с final аргументами в методах и убедитесь что байткод не отличается. Так ведь лень. Иначе бы не спрашивал, а сам посмотрел. ... |
|||
|
:
Нравится:
Не нравится:
|
|||
| 10.06.2014, 17:06 |
|
||
|
Экономно расходование памяти
|
|||
|---|---|---|---|
|
#18+
Alexander A. SakТак ведь лень. Иди компилируй. ... |
|||
|
:
Нравится:
Не нравится:
|
|||
| 10.06.2014, 18:54 |
|
||
|
Экономно расходование памяти
|
|||
|---|---|---|---|
|
#18+
BlazkowiczСкомпилируйте класс с final аргументами в методах и убедитесь что байткод не отличается.Ну так у вас и с volatile байт-код не будет отличаться. Это ни о чем не говорит. Важен не байткод, а то, как это на самом деле работает в рантайме. И final запросто может быть быстрее из-за того, что JIT может более агрессивно оптимизировать доступ к нему. А в каких-то крайних сценариях наоборот может быть медленнее, из-за продолбанных реордерингов, которые могли бы ускорить работу конкретной процедуры. ... |
|||
|
:
Нравится:
Не нравится:
|
|||
| 10.06.2014, 20:06 |
|
||
|
Экономно расходование памяти
|
|||
|---|---|---|---|
|
#18+
DEVcoachBlazkowiczСкомпилируйте класс с final аргументами в методах и убедитесь что байткод не отличается.Ну так у вас и с volatile байт-код не будет отличаться. Это ни о чем не говорит. Важен не байткод, а то, как это на самом деле работает в рантайме. И final запросто может быть быстрее из-за того, что JIT может более агрессивно оптимизировать доступ к нему. А в каких-то крайних сценариях наоборот может быть медленнее, из-за продолбанных реордерингов, которые могли бы ускорить работу конкретной процедуры.Тьфу блин, в аргументах ! Тогда мой пост не валиден. ... |
|||
|
:
Нравится:
Не нравится:
|
|||
| 10.06.2014, 20:07 |
|
||
|
Экономно расходование памяти
|
|||
|---|---|---|---|
|
#18+
набросал два теста, по времени тоже самое, интеренсно какой результат по размеру памяти? в этом профайлере потеряться можно... если кому-то не трудно измерить, то было бы интересно! Код: java 1. 2. 3. 4. 5. 6. 7. 8. 9. 10. 11. 12. 13. 14. 15. 16. 17. 18. 19. 20. 21. 22. 23. 24. 25. 26. 27. 28. 29. 30. 31. 32. 33. 34. Код: java 1. 2. 3. 4. 5. 6. 7. 8. 9. 10. 11. 12. 13. 14. 15. 16. 17. 18. 19. 20. 21. 22. 23. 24. 25. 26. 27. 28. 29. 30. 31. 32. 33. 34. ... |
|||
|
:
Нравится:
Не нравится:
|
|||
| 11.06.2014, 13:16 |
|
||
|
Экономно расходование памяти
|
|||
|---|---|---|---|
|
#18+
офигеть, я увеличил цикл до 30000, чтоб по настоящему, и мои замеры показали, что экономия памяти достигает как мин. 78 % для умной коллекции ... |
|||
|
:
Нравится:
Не нравится:
|
|||
| 11.06.2014, 14:15 |
|
||
|
Экономно расходование памяти
|
|||
|---|---|---|---|
|
#18+
rema174офигеть, я увеличил цикл до 30000, чтоб по настоящему, и мои замеры показали, что экономия памяти достигает как мин. 78 % для умной коллекции А что удивляет? Посмотри размер типа char и размер экземпляра Character. ... |
|||
|
:
Нравится:
Не нравится:
|
|||
| 11.06.2014, 14:21 |
|
||
|
Экономно расходование памяти
|
|||
|---|---|---|---|
|
#18+
Самое разумное - использовать для экономии тот факт, что оракловская jvm выравнивает каждый обьект по границе кешлайна, который составляет 64 байта на х86(_64) архитектуре. Делается это для отпимизации многопоточной работы: на жаве один поток с одним обьектом и другой с другим будут работать быстро, тогда как на с++ подобное будет зависеть от того как эти обьекты аллоцировались - можно налететь на false sharing. поэтому возможны порой странный вещи. Миллион обьектов class Foo{ int t; } и миллион обьектов class Foo{ int t; int g; long p; } Должны по идее занимать одинаково, потому что оба обьекта влазят в 64байта. По этой причине, много мелких долгоживущих обьектов - это не очень хорошо, и если можно без них обойтись, то такой путь следует предпочесть... ... |
|||
|
:
Нравится:
Не нравится:
|
|||
| 11.06.2014, 19:02 |
|
||
|
Экономно расходование памяти
|
|||
|---|---|---|---|
|
#18+
У меня была идея в POJO объединять строковые поля в одно. И аннотациями описывать. ... |
|||
|
:
Нравится:
Не нравится:
|
|||
| 11.06.2014, 19:27 |
|
||
|
Экономно расходование памяти
|
|||
|---|---|---|---|
|
#18+
chabapokиспользовать для экономии тот факт, что оракловская jvm выравнивает каждый обьект по границе кешлайна, который составляет 64 байта на х86(_64) архитектуре. Доклад с примерами, как это проявляется в разных случаях: ... |
|||
|
:
Нравится:
Не нравится:
|
|||
| 12.06.2014, 00:14 |
|
||
|
Экономно расходование памяти
|
|||
|---|---|---|---|
|
#18+
maytonУ меня была идея в POJO объединять строковые поля в одно. И аннотациями описывать. с разделителем? чтобы доставать потом первый - name, второй - city и т.д.? а аннотации как помогут? ... |
|||
|
:
Нравится:
Не нравится:
|
|||
| 12.06.2014, 08:55 |
|
||
|
Экономно расходование памяти
|
|||
|---|---|---|---|
|
#18+
chabapokСамое разумное - использовать для экономии тот факт, что оракловская jvm выравнивает каждый обьект по границе кешлайна, который составляет 64 байта на х86(_64) архитектуре. Делается это для отпимизации многопоточной работы: на жаве один поток с одним обьектом и другой с другим будут работать быстро, тогда как на с++ подобное будет зависеть от того как эти обьекты аллоцировались - можно налететь на false sharing. поэтому возможны порой странный вещи. Миллион обьектов class Foo{ int t; } и миллион обьектов class Foo{ int t; int g; long p; } Должны по идее занимать одинаково, потому что оба обьекта влазят в 64байта. По этой причине, много мелких долгоживущих обьектов - это не очень хорошо, и если можно без них обойтись, то такой путь следует предпочесть...Вы что-то оооочень сильно путаете. 1) Выравнивание по кэшлайну невозможно в принципе . Потому что не существует инструкции процессора, которая позволила бы ему записать конркетное значение конкретно в начало кэш-линии. 2) Выравнивание по кэшлайну не нужно . Потому что мы никогда не читаем объект целиком. Мы можем прочитать его адрес, его поле, и т.д.. Но мы никогда не вычитываем весь объект полностью сразу же. Вы все это спутали с выравниванием по 64-битной сетке в памяти. Это да, такое есть. Смысл заключается в том, что бы можно было прочитать конкретное поле объекта за минимальное количество чтений из памяти. Адреса в памяти у нас идут так: 0, 8, 16 ... И если вы запишете Long по адресу 8, то сможете его считать за один раз. А если вы его запишете по адресу 12, то вам сначала придется прочитать адрес 8, взять 4 младших байта, потом прочитать адрес 16, взять 4 старших байта, и потом их объединить. Добавьте к этому проблему с конкурентным доступом (один заканчивает запись по адресу 16, а другой начинает вычитывать два адреса => будет прочитана какая-то хрень). По этой же причине ваш пример с размерами классов неверен. Первый класс займет 16 байт (12 хеадер + 4 int). А второй займет 12 + 4 + 4 + 8 = 28 + 4 (выравнивание) = 32 байта. Ни о какой привязке к кэшлайнам речи не идет. Это легко можно проверить следующим кодом: Код: java 1. 2. 3. 4. 5. 6. 7. 8. 9. 10. 11. 12. 13. 14. 15. 16. 17. 18. 19. 20. 21. 22. 23. 24. 25. ... |
|||
|
:
Нравится:
Не нравится:
|
|||
| 12.06.2014, 11:34 |
|
||
|
Экономно расходование памяти
|
|||
|---|---|---|---|
|
#18+
chabapokПо этой причине, много мелких долгоживущих обьектов - это не очень хорошо, и если можно без них обойтись, то такой путь следует предпочесть...Иметь много мелких долгоживущих объектов плохо, но по совершенно другой причине - высокая фрагментация хипа в tenured generation, которая может приводить к тормозам GC на мажорных сборках. ... |
|||
|
:
Нравится:
Не нравится:
|
|||
| 12.06.2014, 11:36 |
|
||
|
Экономно расходование памяти
|
|||
|---|---|---|---|
|
#18+
rema174maytonУ меня была идея в POJO объединять строковые поля в одно. И аннотациями описывать. с разделителем? чтобы доставать потом первый - name, второй - city и т.д.? а аннотации как помогут? Ну... не POJO. А скорее Entity с геттерами. Я исходил из предположения что если entity содержит over 100 полей типа String и каждый объект всегда занимает какое-то место, то на уровне storage коллекции таких сущностей можно получить выигрыш если объединить эти строки в одну большую. Getter должен соотв. реализовывать логику извлечения этой сжатой строки из общего пакета строк. Далее, если наблюдать коллекции по вертикали то можно оптимизировать некоторые справончые fields (которые содержат ограниченный набор значений {"male"|"female"}) или соптимизировать поля в которые кладут только одно-байтные (по смыслу) ASCII строки. ... |
|||
|
:
Нравится:
Не нравится:
|
|||
| 12.06.2014, 11:55 |
|
||
|
Экономно расходование памяти
|
|||
|---|---|---|---|
|
#18+
DEVcoachПо этой же причине ваш пример с размерами классов неверен. Первый класс займет 16 байт (12 хеадер + 4 int). А второй займет 12 + 4 + 4 + 8 = 28 + 4 (выравнивание) = 32 байта. Ни о какой привязке к кэшлайнам речи не идет. Это легко можно проверить следующим кодом: Давайте различать кучу и ее дамп. В хипдампе выравнивания нет - это понятно. И ваш код относится к дампу. А вы попытайтесь воспроизвести false sharing работая с разными объектами из разных потоков. Если получится - это значит, что jvm может положить два обьекта в один 64-байтовый блок. И сделайте сет из 2млн интов и сравните с сетом на 2 млн лонгов. Память жрать должно одинаково, по крайней мере раньше так было. Поделите размер на 2млн. Должно получится около 64. ... |
|||
|
:
Нравится:
Не нравится:
|
|||
| 17.06.2014, 09:23 |
|
||
|
|

start [/forum/topic.php?fid=59&msg=38668292&tid=2127042]: |
0ms |
get settings: |
6ms |
get forum list: |
10ms |
check forum access: |
2ms |
check topic access: |
2ms |
track hit: |
143ms |
get topic data: |
8ms |
get forum data: |
2ms |
get page messages: |
39ms |
get tp. blocked users: |
1ms |
| others: | 205ms |
| total: | 418ms |

| 0 / 0 |
