Форум программистов, компьютерный форум, киберфорум
Java SE (J2SE)
Войти
Регистрация
Восстановить пароль
Блоги Сообщество Поиск Заказать работу  
 
Рейтинг 4.92/13: Рейтинг темы: голосов - 13, средняя оценка - 4.92
 Аватар для nnnikotinnn995
7 / 7 / 4
Регистрация: 07.07.2011
Сообщений: 583

Профайлер для исполняемого jar файла

09.06.2017, 21:59. Показов 2855. Ответов 15
Метки нет (Все метки)

Студворк — интернет-сервис помощи студентам
Здравствуйте. Посоветуйте пожалуйста профайлер для готового сервер приложения .jar (использующего технологию Nio) , которое спустя 2 часа после его запуска (или при большом количестве подключаемых клиентов) начинает тормозить и у клиентов возникают лаги. Цель найти то место в коде, где чаще всего начинают возникать задержки. Дебаг вряд ли сможет подойти, потому как он останавливает выполнение программы. Можно ли с помощью профайлера определить переменные/методы в которых чаще всего возникает задержка, (сижу в eclipse)?
0
Programming
Эксперт
39485 / 9562 / 3019
Регистрация: 12.04.2006
Сообщений: 41,671
Блог
09.06.2017, 21:59
Ответы с готовыми решениями:

Создание исполняемого jar файла
Пишу в Intellij IDEA 13 CE, через подключенный к нему maven создал jar файл(через плагин к maven "maven-jar-plugin"). В итоге...

Имя исполняемого файла для Android
Почему для Android-а исполняемые файлы после сборки как отладочного варианта, так и реализа имеют одинаковое имя: “QtApp-debug.apk”. При...

Программа для сжатия исполняемого файла
Здравствуйте не подскажите программу для сжатия исполняемого файла или есть ли такая функция в VS 2010

15
Эксперт Java
 Аватар для turbanoff
4094 / 3828 / 745
Регистрация: 18.05.2010
Сообщений: 9,331
Записей в блоге: 12
12.06.2017, 13:03
Проще всего, запустить Flight Recorder, в тот момент, когда проблема начинает воспроизводиться.
Записать, несколько минут, и потом посмотреть в Java Mission Control
jmc встроен в Oracle JDK, ничего дополнительного ставить не нужно.
https://docs.oracle.com/javaco... m#JFRUH164

Также полезно включить GC логи, и посмотреть, не случается ли постоянный Full GC во время повторения проблемы.
Если случается - нужно снять Heap Dump (можно с помощью jcmd) и потом уже смотреть, кто сожрал память.
1
 Аватар для nnnikotinnn995
7 / 7 / 4
Регистрация: 07.07.2011
Сообщений: 583
12.06.2017, 16:52  [ТС]
Спасибо буду разбираться. Просто в eclipseуже есть profile as, но он не запускается (скрин 1,2), а при попытке создать конфигурацию ругается на то, что не может найти GWT который я вообще не использую, может он для чего то другого создан? И по диспетчеру задач у меня растет загрузка процессора ,озу почти не меняется, как вы думаете могут ли объекты кучи забивать кеш процессора и тормозить его (HashMap способен на такое)?
0
 Аватар для nnnikotinnn995
7 / 7 / 4
Регистрация: 07.07.2011
Сообщений: 583
12.06.2017, 17:12  [ТС]
вот скрины
Миниатюры
Профайлер для исполняемого jar файла   Профайлер для исполняемого jar файла   Профайлер для исполняемого jar файла  

0
 Аватар для nnnikotinnn995
7 / 7 / 4
Регистрация: 07.07.2011
Сообщений: 583
16.06.2017, 17:39  [ТС]
Второй день занимаюсь этим вопросом, но ни как не удается в jmc найти указатель на строку в коде, нашел только hot metods (скрин 1) а в каком месте кода он вызывается не ясно,это возможно в Flight Recorder или в Memory Analyzer? К стати дамп кучи можно получить и в jconsole (скрин 2), получить из него дамп и и открыть в Memory Analyzer. Решил вспомнить основы и как пишет Экель "... в Java существует сборщик мусора (garbage collector) ,который наблюдает за объектами, созданными оператором new, и определяет, на какие из них больше нет ссылок. Тогда он освобождает память от этих объектов..." , а если объект создан внутри метода не через new а получен из (например) из List или HashMap , то тогда он разые не попадает в кучу и не удаляется?

Java
1
2
3
4
5
6
7
8
9
10
11
12
private Map pendingDatan = new HashMap();
public void send(SocketChannel socket, byte[] data,int KEYN) {
 synchronized (this) {
     synchronized (this.pendingDatan) {
 List queue_get_byten = (List) this.pendingDatan.get(KEYN);// этот объект останется в памяти после скобки и в кучу не //попадет ?
ByteBuffer bufn=ByteBuffer.allocate(1524);//или этот объект  тоже останется в памяти? 
     if (queue_get_byten == null || queue_get_byten.isEmpty()) {
         queue_get_byten = new ArrayList();
                        }
     queue_get_byten.add(data);this.pendingDatan.put(KEYN, queue_get_byten);    
...
}
И еще про куче Экель писал следующее;
"3.Куча. Пул памяти общего назначения (находится так же в RAM)" ,это точно так, куча не попадают в кеш процессора?
Миниатюры
Профайлер для исполняемого jar файла   Профайлер для исполняемого jar файла  
0
Эксперт Java
 Аватар для turbanoff
4094 / 3828 / 745
Регистрация: 18.05.2010
Сообщений: 9,331
Записей в блоге: 12
16.06.2017, 23:56
Цитата Сообщение от nnnikotinnn995 Посмотреть сообщение
а если объект создан внутри метода не через new а получен из (например) из List или HashMap , то тогда он разые не попадает в кучу и не удаляется?
Так перед тем как попасть в List/Map - его кто-то создал. Объекты просто так не теряются GC всё знает.

Добавлено через 2 минуты
Вы где-нибудь вызываете pendingDatan.remove? Или вы туда только добавляете объекты?
0
 Аватар для nnnikotinnn995
7 / 7 / 4
Регистрация: 07.07.2011
Сообщений: 583
17.06.2017, 15:03  [ТС]
Цитата Сообщение от turbanoff Посмотреть сообщение
Так перед тем как попасть в List/Map - его кто-то создал.
Это да, но например в ByteBuffer bufn=ByteBuffer.allocate(1524); нет слова new, оно внутри метода allocate скрывается или вообще в классе ByteBuffer?
Цитата Сообщение от turbanoff Посмотреть сообщение
Вы где-нибудь вызываете pendingDatan.remove? Или вы туда только добавляете объекты?
Конечно, я делаю это когда клиент выходит из приложения или из группы клиентов
Java
1
2
3
4
5
6
7
8
9
10
11
12
public void CLIENT_CLOSEN(int keyn,SocketChannel socketChannel){
//очистка всей очереди данных группы клиентов 
synchronized (this.pendingDatan) {
List queue_teamn = (List) this.pendingDatan.get(num_team_isn_donen[keyn]);
if(queue_teamn!=null&&!queue_teamn.isEmpty()){  
    while (!queue_teamn.isEmpty()) {
        queue_teamn.remove(0);}queue_teamn=null;
if(pendingDatan.containsKey(num_team_isn_donen[keyn]))pendingDatan.remove(num_team_isn_donen[keyn]);
                       }
}
...
}
Хочу на днях создать тему "Производительность java.nio" и представить свой шаблон соединения (надо свой код упростить до понябельного вида). Я использую vps (windows2012) и когда немного разобрался с jmc попробовал запустить его на сервере где в данный момент раз в 2 секунды лагает прога/сервер ( лаги 100-200мс, не знаю, может это норма но первый час работы проги сервера их почему то нет - точнее 1 раз в минуту). Запустил Flight Recorder и jmc заругался
"The in memory agent can not be started on this JVM, since attach is not supported! If you're trying to connect to a 32-bit JVM with a 64-bit Mission Control or vice versa, start the management agent manually by using the JVM flag -Dcom.sun.management.jmxremote for your JVM prior to trying to connect to it.
"

jconcole то же незапускается, походу сервер 64 битный и тут остается или останавливать сервер и переустанавливать на него 64 битный jdk , или запустить какой то флаг Dcom.sun.management.jmxremote. Вы случайно с этим не сталкивались, можно ли запустить этот флаг не из командной строки, так как я из командной строки запустил сервер-прогу jar?

Добавлено через 3 минуты
Вот скрин
Миниатюры
Профайлер для исполняемого jar файла  
0
Эксперт Java
 Аватар для turbanoff
4094 / 3828 / 745
Регистрация: 18.05.2010
Сообщений: 9,331
Записей в блоге: 12
17.06.2017, 16:07
Можно попробовать включить этот флажок с помощью jcmd когда процесс уже запущен
Code
1
jcmd <PID> ManagementAgent.start_local
Добавлено через 2 минуты
Цитата Сообщение от nnnikotinnn995 Посмотреть сообщение
ByteBuffer bufn=ByteBuffer.allocate(1524); нет слова new, оно внутри метода allocate скрывается или вообще в классе ByteBuffer?
Так откройте исходники и посмотрите! Это же очень просто, если вы ползуетесь IDE.
Java
1
2
3
4
5
    public static ByteBuffer allocate(int capacity) {
        if (capacity < 0)
            throw new IllegalArgumentException();
        return new HeapByteBuffer(capacity, capacity);
    }
Добавлено через 2 минуты
Так что с GC? Вы включили логи? Какой GC используется? Дефолтный?
Какой размер Heap-а выставлен? (опция -Xmx)
Во время лага, запускается GC или тормозит именно программа?
0
 Аватар для nnnikotinnn995
7 / 7 / 4
Регистрация: 07.07.2011
Сообщений: 583
18.06.2017, 08:41  [ТС]
Цитата Сообщение от turbanoff Посмотреть сообщение
Можно попробовать включить этот флажок с помощью jcmd когда процесс уже запущен
Код
jcmd <PID> ManagementAgent.start_local
Не получилось, пишет что не может присоединиться к 64 битному процессу, наверно надо все 64 битное поставить, как сделаю -отпишусь.
Миниатюры
Профайлер для исполняемого jar файла  
0
 Аватар для nnnikotinnn995
7 / 7 / 4
Регистрация: 07.07.2011
Сообщений: 583
18.06.2017, 15:38  [ТС]
Арендовал новый (идентичный старому) vps (windows 2012) и поставил на него все последнее 64 битное (jdk-8u131-windows-x64 и eclipse-inst-win64-Eclipse Java Neon), jmc запускает и записывает FR но не может открыть полученный файл - пишет
Java
1
Could not download recording for TN1.java.io.FileNotFoundException: No chunks
Java
1
2
3
4
5
6
7
8
9
[jfr][WARN ][164.108] VMJFR.finishChunk ignored an exception
[jfr][WARN ][164.108] java.io.IOException:Could not rename C:\Users\Администратор\AppData\Local\Temp\2\2017_06_18_15_21_45_2752\2017_06_18_15_23_10_2752_0.jfr.part to C:\Users\Администратор\AppData\Local\Temp\2\2017_06_18_15_21_45_2752\2017_06_18_15_23_10_2752_0.jfr
[jfr][WARN ][164.108]    oracle.jrockit.jfr.RepositoryChunk$2.run(RepositoryChunk.java:121)
[jfr][WARN ][164.109]    oracle.jrockit.jfr.RepositoryChunk$2.run(RepositoryChunk.java:116)
[jfr][WARN ][164.109]    java.security.AccessController.doPrivileged(Native Method)
[jfr][WARN ][164.109]    java.security.AccessController.doPrivileged(Unknown Source)
[jfr][WARN ][164.109]    oracle.jrockit.jfr.RepositoryChunk.finish(RepositoryChunk.java:116)
[jfr][WARN ][164.109]    oracle.jrockit.jfr.RepositoryChunk.finish(RepositoryChunk.java:57)
[jfr][WARN ][164.109]    oracle.jrockit.jfr.VMJFR.finishChunk(VMJFR.java:357)
То есть не может переименовать файл находящийся в папке темп. Все скачано с официальных сайтов, однако JMX console запускается, как Вы думаете в чем может быть причина?
Миниатюры
Профайлер для исполняемого jar файла  
0
Эксперт Java
 Аватар для turbanoff
4094 / 3828 / 745
Регистрация: 18.05.2010
Сообщений: 9,331
Записей в блоге: 12
18.06.2017, 16:21
Может что-то не так с правами?
Попробуйте записанный jfr файл себе скопировать и открыть локально.
0
 Аватар для nnnikotinnn995
7 / 7 / 4
Регистрация: 07.07.2011
Сообщений: 583
18.06.2017, 16:28  [ТС]
Пробовал у себя на windows7 32бита ,пишет что не может ивенты получить из jfr
Java
1
2
Could not load events from C:\sen\comnikitintestn2NRFN.jfr
com.jrockit.mc.flightrecorder.internal.parser.binary.InvalidFlrFileException
, причем на windows7 32 бита FR работает.
Миниатюры
Профайлер для исполняемого jar файла  
0
 Аватар для nnnikotinnn995
7 / 7 / 4
Регистрация: 07.07.2011
Сообщений: 583
18.06.2017, 17:07  [ТС]
Решился я на абсурдный шаг - и он сработал:
Java
1
 java.io.IOException:Could not rename C:\Users\Администратор\AppData\Local\Temp\2\2017_06_18_15_21_45_2752\2017_06_18_15_23_10_2752_0.jfr.part to C:\Users\Администратор\AppData\Local\Temp\2\2017_06_18_15_21_45_2752\2017_06_18_15_23_10_2752_0.jfr
нашел путь где jmc не может переименовать и в нужном файле не хватало в конце имени 3-5 символов и расширения jfr - поставил сам и смог его открыть в jmc, более того когда при старте нажимаю на справку (скрин 1) пишет сервер плохой - http error :500 (скрин 2), как Вы думаете это дело в машине (vps) или надо что то доустановить/настроить?
Миниатюры
Профайлер для исполняемого jar файла   Профайлер для исполняемого jar файла  
0
 Аватар для nnnikotinnn995
7 / 7 / 4
Регистрация: 07.07.2011
Сообщений: 583
20.06.2017, 09:24  [ТС]
Вот общая картина FR за 10 минут (скрин1), по графику used heap кучи нет роста нижнего уровня (скрин 2 ), единственное что изменилось со вчерашнего дня (12 часов назад примерно) - commiteted heap вырос с 80 М до 190 М (вчерашний день -скрин 3), может ли этот рост способствовать понижению производительности?
Во вкладке code самый горячий метод sun.nio.ch.SocketChannelImpl.read(ByteBu ffer) (скрин 4), так же он отмечен в ивентах (скрин 5). Не понятно что значит горячие методы - те которые кучу забивают и садят производительность или просто чаще всего вызываются? Вот мой метод read
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
35
36
37
38
39
40
private void read(SelectionKey key) throws IOException {
    SocketChannel socketChannel = (SocketChannel) key.channel();
    int keyn=(Integer)key.attachment();
    this.readBuffer.clear();
        int count_byte_in = socketChannel.read(this.readBuffer);
    if(count_byte_in>0){synchronized(this){newintenresn[keyn]=false;}
    int KEYN=-keyn;
    this.worker.processData(this, socketChannel, this.readBuffer.array(),count_byte_in,KEYN);   
    this.readBuffer.flip(); 
    }
}
/// и где он вызывается примерно
public void SMAIN() throws IOException, InterruptedException {
        readBuffer = ByteBuffer.allocate(sizen);
this.selector = this.initSelector();
 Iterator<SelectionKey> iterator = null;              
while(true) { ...
this.selector.select();
    iterator = selector.selectedKeys().iterator();     
            while (iterator.hasNext()) {
                SelectionKey   key =  iterator.next();
                iterator.remove();
                try {   
                    if (!key.isValid()||key==null) {
                        continue;
                    }
if (key.isAcceptable()) {
    //
synchronized(this){accept(key);}
                       }
else if(key.isConnectable()){
                        SocketChannel sock =(SocketChannel) key.channel();
                        sock.finishConnect();
                            }
else if (key.isValid()&&key.isWritable()) {
    write(key);
 }else if (key.isReadable()) {
///////////////////ВОТ ОН
     read(key);
                             }
Конечно из этих данных сложно что то предположить но если этот метод частенько встречается в FR то он ли виноват в понижение производительности, о чем это может говорить ( просто есть другие методы в которых гораздо больше вычислений и используется Map/Lict но они почему то в jmc ниже этого метода)?
Миниатюры
Профайлер для исполняемого jar файла   Профайлер для исполняемого jar файла   Профайлер для исполняемого jar файла  

Профайлер для исполняемого jar файла   Профайлер для исполняемого jar файла  
0
 Аватар для nnnikotinnn995
7 / 7 / 4
Регистрация: 07.07.2011
Сообщений: 583
23.06.2017, 09:17  [ТС]
Я нашел одну из утечек памяти, оказалось что сервер не всегда может увидеть что клиент вышел из приложения, то есть
чтение из канала в битбуфер не всегда может поймать -1
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
35
36
this.readBuffer.clear();
    int count_byte_in;
try {
    count_byte_in = socketChannel.read(this.readBuffer);
}catch (IOException e) {
        synchronized(this){ 
            if(key!=null){
            CLIENT_CLOSEN(keyn,socketChannel); 
            try {
                key.interestOps(key.interestOps() & ~SelectionKey.OP_WRITE);
                key.interestOps(key.interestOps() & ~SelectionKey.OP_READ);
                key.channel().close();                   
            } catch (IOException cex) {
            }
            key.cancel();key=null;
            now_maxcount_client_in_gamen--;count_exit_clientsn++;
                           } 
            return;
                          }
                      }
// сервер не всегда может поймать выход клиента
if (count_byte_in == -1) {
synchronized(this){ 
if(key!=null){
CLIENT_CLOSEN(keyn,socketChannel); 
try {
    key.interestOps(key.interestOps() & ~SelectionKey.OP_WRITE);
    key.interestOps(key.interestOps() & ~SelectionKey.OP_READ);
    key.channel().close();                   
} catch (IOException cex) {
}
key.cancel();key=null;
               } 
return;
              } 
                        }
Я стал убивать всех клиентов, если от них нет данных в течение 10 минут и стало значительно лучше (уже 12 часов прошло и лагов почти нет). Но я заметил в jmc что когда верхний пик графика used heap возрастает , то вместе с ним не только committed heap возрастает, но и очистка used heap идет по верхнему пику (не раньше, скрин 1), то есть если в начале used heap очищается на 32 М , а потом по каким то причинам он вырос до 175 М и очистился, то в следующий раз GC сработает не на 32 М, а на 175 М. Это так и должно быть? К стати самый горячий метод java.util.Scanner.next(), я с помошью него ищу данные клиента и их заменяю на новые, делаю так
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
...
if(client_time_win[num_in_fn[kn]]<prefs.getFloat("clntimewin"+num_in_fn[kn]+";"+numstgnown2+";"+stgnown2,defaulttimewin)){
    prefs.putFloat("clntimewin"+num_in_fn[kn]+";"+numstgnown2+";"+stgnown2,client_time_win[num_in_fn[kn]]);
prefs.flush();}
...
//вот как выглядит getFloat
public float getFloat(String namen, float defaulttimewin) {
      Scanner scanner;float getfloatn=defaulttimewin;name_is_found=false;
        try {
            scanner = new Scanner(Paths.get(fileNamefloatsn));
               scanner.useDelimiter(System.getProperty("line.separator"));
while(scanner.hasNext()){
    getfloatn = ingetFloat(scanner.next(),namen,defaulttimewin);if(name_is_found)break;
                  }scanner.close();
        } catch (IOException e) {
            e.printStackTrace();
        }
        return getfloatn;
}
// и как ingetFloat на который по мнению jmc больше всего нагрузка 
private float ingetFloat(String line,String namen,float ndefaultn) {
    float float_countn=ndefaultn;    
    Scanner scanner = new Scanner(line);
    scanner.useDelimiter(">");
String name = scanner.next();
float_countn=Float.valueOf(scanner.next()).floatValue();
if(name.matches(namen)){name_is_found=true;return float_countn;}else return ndefaultn;}
Не знаю, может сканер scanner.next() не лучший способ поиска имени в файле?
Миниатюры
Профайлер для исполняемого jar файла  
0
Эксперт Java
 Аватар для turbanoff
4094 / 3828 / 745
Регистрация: 18.05.2010
Сообщений: 9,331
Записей в блоге: 12
23.06.2017, 11:40
Цитата Сообщение от nnnikotinnn995 Посмотреть сообщение
следующий раз GC сработает не на 32 М, а на 175 М. Это так и должно быть?
Да. Так и будет пока не достигнется максимум объёма heap-а. Таким образом текущий размер heap-а адаптируется к запросам приложения.

Добавлено через 52 секунды
Scanner - не самая быстрая штука. Внутри него используются регулярки.
Если нужно его ускорить, лучше парсить руками.
0
Надоела реклама? Зарегистрируйтесь и она исчезнет полностью.
inter-admin
Эксперт
29715 / 6470 / 2152
Регистрация: 06.03.2009
Сообщений: 28,500
Блог
23.06.2017, 11:40
Помогаю со студенческими работами здесь

Ищу программу для анализа исполняемого файла
Добрый день всем, пересмотрел везде где только можно, ищу программу которая анализирует и выдает лог при запуске выбранного исполняемого...

Как назначить иконку для исполняемого файла программы
Microsoft Visual C# 2008 Express Edition как сделать,чтобы ехе файл выглядел как красивая иконка а не стандартно. Как изменить имя формы,...

Замена параметра запуска для исполняемого файла в ярлыке
Доброго времени суток. Задача такая: нужно пройтись батником по Documents and Settings всех пользователей, найти все *1c*.lnk и...

Как создать exe контейнер для исполняемого файла с ограничениями
Как создать exe контейнер для исполняемого файла с встроенной системой ограничений для пользователя, например по конечной дате...

Написать код исполняемого файла для очистки экрана и вывода списка файлов / каталогов текущего каталога
У кого есть исходники хотя бы одной программы прошу поделиться. 1. Написать код исполняемого файла для очистки экрана и вывода списка...


Искать еще темы с ответами

Или воспользуйтесь поиском по форуму:
16
Ответ Создать тему
Новые блоги и статьи
SDL3 для Web (WebAssembly): Обработчик клика мыши в браузере ПК и касания экрана в браузере на мобильном устройстве
8Observer8 02.02.2026
Содержание блога Для начала пошагово создадим рабочий пример для подготовки к экспериментам в браузере ПК и в браузере мобильного устройства. Потом напишем обработчик клика мыши и обработчик. . .
Философия технологии
iceja 01.02.2026
На мой взгляд у человека в технических проектах остается роль генерального директора. Все остальное нейронки делают уже лучше человека. Они не могут нести предпринимательские риски, не могут. . .
SDL3 для Web (WebAssembly): Вывод текста со шрифтом TTF с помощью SDL3_ttf
8Observer8 01.02.2026
Содержание блога В этой пошаговой инструкции создадим с нуля веб-приложение, которое выводит текст в окне браузера. Запустим на Android на локальном сервере. Загрузим Release на бесплатный. . .
SDL3 для Web (WebAssembly): Сборка C/C++ проекта из консоли
8Observer8 30.01.2026
Содержание блога Если вы откроете примеры для начинающих на официальном репозитории SDL3 в папке: examples, то вы увидите, что все примеры используют следующие четыре обязательные функции, а. . .
SDL3 для Web (WebAssembly): Установка Emscripten SDK (emsdk) и CMake для сборки C и C++ приложений в Wasm
8Observer8 30.01.2026
Содержание блога Для того чтобы скачать Emscripten SDK (emsdk) необходимо сначало скачать и уставить Git: Install for Windows. Следуйте стандартной процедуре установки Git через установщик. . . .
SDL3 для Android: Подключение Box2D v3, физика и отрисовка коллайдеров
8Observer8 29.01.2026
Содержание блога Box2D - это библиотека для 2D физики для анимаций и игр. С её помощью можно определять были ли коллизии между конкретными объектами. Версия v3 была полностью переписана на Си, в. . .
Инструменты COM: Сохранение данный из VARIANT в файл и загрузка из файла в VARIANT
bedvit 28.01.2026
Сохранение базовых типов COM и массивов (одномерных или двухмерных) любой вложенности (деревья) в файл, с возможностью выбора алгоритмов сжатия и шифрования. Часть библиотеки BedvitCOM Использованы. . .
SDL3 для Android: Загрузка PNG с альфа-каналом с помощью SDL_LoadPNG (без SDL3_image)
8Observer8 28.01.2026
Содержание блога SDL3 имеет собственные средства для загрузки и отображения PNG-файлов с альфа-каналом и базовой работы с ними. В этой инструкции используется функция SDL_LoadPNG(), которая. . .
КиберФорум - форум программистов, компьютерный форум, программирование
Powered by vBulletin
Copyright ©2000 - 2026, CyberForum.ru