powered by simpleCommunicator - 2.0.61     © 2026 Programmizd 02
Целевая тема:
Создать новую тему:
Автор:
Закрыть
Цитировать
Форумы / Java [игнор отключен] [закрыт для гостей] / Экономно расходование памяти
21 сообщений из 21, страница 1 из 1
Экономно расходование памяти
    #38666209
rema174
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Гость
Подскажите приемы для экономного расходования-снижения памяти, используемой приложением. По этой теме не так много материала. Иногда встречаются такие советы:

Случай 1, вместо этого:
Код: java
1.
2.
3.
Elem e;
e = new HeavyElem();
e = new HeavyElem();

делают так:
Код: java
1.
2.
3.
4.
Elem e;
e = new HeavyElem();
e = null;
e = new HeavyElem();



Случай 2:
передавая в метод объект класса, перед выходом из метода, делают:
Код: java
1.
object = null;



Случай 3:
Предлагают использовать Trove library для коллекций, насколько это актуально?
...
Рейтинг: 0 / 0
Экономно расходование памяти
    #38666223
Фотография Blazkowicz
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Участник
rema174Подскажите приемы для экономного расходования-снижения памяти, используемой приложением.
Java Memory Profiler - самый важный приём. Превентивные оптимизации - зло.
rema174Случай 1, вместо этого:
Код: java
1.
2.
3.
Elem e;
e = new HeavyElem();
e = new HeavyElem();

делают так:
Код: java
1.
2.
3.
4.
Elem e;
e = new HeavyElem();
e = null;
e = new HeavyElem();



Ерунда. Разве что речь о какой-то экстравагантной Java вроде J2ME. И то не факт что там такое нужно.

rema174Случай 2:
передавая в метод объект класса, перед выходом из метода, делают:
Код: java
1.
object = null;



Для аргумента? Ну, бред же.

rema174Предлагают использовать Trove library для коллекций, насколько это актуально?
Ну, актуально иногда. Если у вас большие массивы примитивов, то использованеи оберток повлечет за собой дополнительные расходы по памяти. Тогда можно взять коллекции созданые для примитивов. Почему нет? Или, например, от String отказаться в пользу char[] или даже byte[]. Тоже имеет смысл в качестве оптимизации, а не в качетсве практики.
...
Рейтинг: 0 / 0
Экономно расходование памяти
    #38666241
rema174
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Гость
Blazkowicz,
насчет первых двух случаев согласен, ерунда
...
Рейтинг: 0 / 0
Экономно расходование памяти
    #38666594
Alexander A. Sak
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Участник
Все не было повода спросить. Тут вроде подходящее место.

А как насчет декларации аргументов final? Встречал в одном проекте обязательность такого. Аргумент -- для увеличения производительности. Сомнения загнал подальше, но они остались.
...
Рейтинг: 0 / 0
Экономно расходование памяти
    #38666623
Фотография Blazkowicz
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Участник
Alexander A. SakВсе не было повода спросить. Тут вроде подходящее место.
А как насчет декларации аргументов final? Встречал в одном проекте обязательность такого. Аргумент -- для увеличения производительности. Сомнения загнал подальше, но они остались.
Скомпилируйте класс с final аргументами в методах и убедитесь что байткод не отличается.
...
Рейтинг: 0 / 0
Экономно расходование памяти
    #38666632
Фотография Blazkowicz
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Участник
BlazkowiczСкомпилируйте класс с final аргументами в методах и убедитесь что байткод не отличается.
Хотя, в Java 8 в метаинформации класса теперь хранятся и "параметры". Но байт-код метода не должен отличаться.
...
Рейтинг: 0 / 0
Экономно расходование памяти
    #38666666
Alexander A. Sak
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Участник
BlazkowiczAlexander A. SakВсе не было повода спросить. Тут вроде подходящее место.
А как насчет декларации аргументов final? Встречал в одном проекте обязательность такого. Аргумент -- для увеличения производительности. Сомнения загнал подальше, но они остались.
Скомпилируйте класс с final аргументами в методах и убедитесь что байткод не отличается.

Так ведь лень. Иначе бы не спрашивал, а сам посмотрел.
...
Рейтинг: 0 / 0
Экономно расходование памяти
    #38666798
Фотография Паша01
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Участник
Alexander A. SakТак ведь лень.
Иди компилируй.
...
Рейтинг: 0 / 0
Экономно расходование памяти
    #38666862
DEVcoach
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Гость
BlazkowiczСкомпилируйте класс с final аргументами в методах и убедитесь что байткод не отличается.Ну так у вас и с volatile байт-код не будет отличаться. Это ни о чем не говорит. Важен не байткод, а то, как это на самом деле работает в рантайме.
И final запросто может быть быстрее из-за того, что JIT может более агрессивно оптимизировать доступ к нему. А в каких-то крайних сценариях наоборот может быть медленнее, из-за продолбанных реордерингов, которые могли бы ускорить работу конкретной процедуры.
...
Рейтинг: 0 / 0
Экономно расходование памяти
    #38666865
DEVcoach
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Гость
DEVcoachBlazkowiczСкомпилируйте класс с final аргументами в методах и убедитесь что байткод не отличается.Ну так у вас и с volatile байт-код не будет отличаться. Это ни о чем не говорит. Важен не байткод, а то, как это на самом деле работает в рантайме.
И final запросто может быть быстрее из-за того, что JIT может более агрессивно оптимизировать доступ к нему. А в каких-то крайних сценариях наоборот может быть медленнее, из-за продолбанных реордерингов, которые могли бы ускорить работу конкретной процедуры.Тьфу блин, в аргументах ! Тогда мой пост не валиден.
...
Рейтинг: 0 / 0
Экономно расходование памяти
    #38667509
rema174
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Гость
набросал два теста, по времени тоже самое, интеренсно какой результат по размеру памяти?
в этом профайлере потеряться можно... если кому-то не трудно измерить, то было бы интересно!

Код: 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.
import java.util.ArrayList;
public class TestArrayListCharacter {
        
	public static void main(String[] args) {
				
		int startTime = (int) System.currentTimeMillis();
		
		ArrayList<Character> list = new ArrayList<>();
		
		String string = "Java - это технология, используемая для разработки "
				+ "приложений, которые делают работу в сети Интернет более "
				+ "увлекательной и удобной. Java отличается от языка "
				+ "программирования javascript, который представляет собой "
				+ "простую технологию для создания веб-страниц и выполняется "
				+ "только в браузере.\n";

		char[] charArray = string.toCharArray();
		
		for(short y=0; y<1000; y++) {
			for(short i=0; i<charArray.length; i++) {
				list.add(charArray[i]);
			}
		}
		
		for(int i=0; i<list.size(); i++)
			System.out.print(list.get(i));
		
		int finishTime = (int) System.currentTimeMillis();

		System.out.println("ArrayList<Character>: " + (finishTime - startTime));
		
	}
	
}


Код: 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.
import org.apache.commons.collections.primitives.ArrayCharList;
public class TestArrayCharList {

	public static void main(String[] args) {

		int startTime = (int) System.currentTimeMillis();

		ArrayCharList arrayCharList = new ArrayCharList();

		String string = "Java - это технология, используемая для разработки "
				+ "приложений, которые делают работу в сети Интернет более "
				+ "увлекательной и удобной. Java отличается от языка "
				+ "программирования javascript, который представляет собой "
				+ "простую технологию для создания веб-страниц и выполняется "
				+ "только в браузере.\n";

		char[] charArray = string.toCharArray();
		
		for(short y=0; y<1000; y++) {
			for (short i = 0; i < charArray.length; i++) {
				arrayCharList.add(charArray[i]);
			}
		}
		
		for(int i=0; i<arrayCharList.size(); i++)
			System.out.print(arrayCharList.get(i));
		
		int finishTime = (int) System.currentTimeMillis();

		System.out.println("ArrayCharList: " + (finishTime - startTime));

	}

}
...
Рейтинг: 0 / 0
Экономно расходование памяти
    #38667600
rema174
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Гость
офигеть, я увеличил цикл до 30000, чтоб по настоящему, и мои замеры показали, что экономия памяти достигает как мин. 78 % для умной коллекции
...
Рейтинг: 0 / 0
Экономно расходование памяти
    #38667611
Фотография Blazkowicz
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Участник
rema174офигеть, я увеличил цикл до 30000, чтоб по настоящему, и мои замеры показали, что экономия памяти достигает как мин. 78 % для умной коллекции
А что удивляет? Посмотри размер типа char и размер экземпляра Character.
...
Рейтинг: 0 / 0
Экономно расходование памяти
    #38668055
chabapok
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Участник
Самое разумное - использовать для экономии тот факт, что оракловская jvm выравнивает каждый обьект по границе кешлайна, который составляет 64 байта на х86(_64) архитектуре.
Делается это для отпимизации многопоточной работы: на жаве один поток с одним обьектом и другой с другим будут работать быстро, тогда как на с++ подобное будет зависеть от того как эти обьекты аллоцировались - можно налететь на false sharing.


поэтому возможны порой странный вещи. Миллион обьектов
class Foo{
int t;
}

и миллион обьектов
class Foo{
int t;
int g;
long p;
}

Должны по идее занимать одинаково, потому что оба обьекта влазят в 64байта.

По этой причине, много мелких долгоживущих обьектов - это не очень хорошо, и если можно без них обойтись, то такой путь следует предпочесть...
...
Рейтинг: 0 / 0
Экономно расходование памяти
    #38668078
Фотография mayton
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Участник
У меня была идея в POJO объединять строковые поля в одно. И аннотациями описывать.
...
Рейтинг: 0 / 0
Экономно расходование памяти
    #38668230
chabapokиспользовать для экономии тот факт, что оракловская jvm выравнивает каждый обьект по границе кешлайна, который составляет 64 байта на х86(_64) архитектуре.

Доклад с примерами, как это проявляется в разных случаях:
YouTube Video
...
Рейтинг: 0 / 0
Экономно расходование памяти
    #38668292
rema174
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Гость
maytonУ меня была идея в POJO объединять строковые поля в одно. И аннотациями описывать.
с разделителем? чтобы доставать потом первый - name, второй - city и т.д.? а аннотации как помогут?
...
Рейтинг: 0 / 0
Экономно расходование памяти
    #38668340
DEVcoach
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Гость
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.
import org.openjdk.jol.info.*;

public class Layout {

    private static class A {
        int a;
    }

    private static class B {
        int a;
        long b;
    }

    private static class C {
        int a;
        int b;
        long c;
    }

    public static void main(String[] args) {
        System.out.println(ClassLayout.parseClass(A.class).toPrintable());
        System.out.println(ClassLayout.parseClass(B.class).toPrintable());
        System.out.println(ClassLayout.parseClass(C.class).toPrintable());
    }
}

...
Рейтинг: 0 / 0
Экономно расходование памяти
    #38668343
DEVcoach
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Гость
chabapokПо этой причине, много мелких долгоживущих обьектов - это не очень хорошо, и если можно без них обойтись, то такой путь следует предпочесть...Иметь много мелких долгоживущих объектов плохо, но по совершенно другой причине - высокая фрагментация хипа в tenured generation, которая может приводить к тормозам GC на мажорных сборках.
...
Рейтинг: 0 / 0
Экономно расходование памяти
    #38668352
Фотография mayton
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Участник
rema174maytonУ меня была идея в POJO объединять строковые поля в одно. И аннотациями описывать.
с разделителем? чтобы доставать потом первый - name, второй - city и т.д.? а аннотации как помогут?
Ну... не POJO. А скорее Entity с геттерами. Я исходил из предположения что если entity содержит
over 100 полей типа String и каждый объект всегда занимает какое-то место, то на уровне
storage коллекции таких сущностей можно получить выигрыш если объединить эти строки
в одну большую. Getter должен соотв. реализовывать логику извлечения этой сжатой строки
из общего пакета строк. Далее, если наблюдать коллекции по вертикали то можно оптимизировать
некоторые справончые fields (которые содержат ограниченный набор значений {"male"|"female"}) или
соптимизировать поля в которые кладут только одно-байтные (по смыслу) ASCII строки.
...
Рейтинг: 0 / 0
Экономно расходование памяти
    #38671271
chabapok
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Участник
DEVcoachПо этой же причине ваш пример с размерами классов неверен. Первый класс займет 16 байт (12 хеадер + 4 int). А второй займет 12 + 4 + 4 + 8 = 28 + 4 (выравнивание) = 32 байта. Ни о какой привязке к кэшлайнам речи не идет. Это легко можно проверить следующим кодом:

Давайте различать кучу и ее дамп. В хипдампе выравнивания нет - это понятно. И ваш код относится к дампу.

А вы попытайтесь воспроизвести false sharing работая с разными объектами из разных потоков. Если получится - это значит, что jvm может положить два обьекта в один 64-байтовый блок.

И сделайте сет из 2млн интов и сравните с сетом на 2 млн лонгов. Память жрать должно одинаково, по крайней мере раньше так было. Поделите размер на 2млн. Должно получится около 64.
...
Рейтинг: 0 / 0
21 сообщений из 21, страница 1 из 1
Форумы / Java [игнор отключен] [закрыт для гостей] / Экономно расходование памяти
Найденые пользователи ...
Разблокировать пользователей ...
Читали форум (0):
Пользователи онлайн (0):
x
x
Закрыть


Просмотр
0 / 0
Close
Debug Console [Select Text]