Java-программирование (1-ые посты) 12.08.2015 / 12:50 | | Naik Пользователь Сейчас: Offline
Имя: %name% Регистрация: 14.03.2010
| Bogdan-G, очевидно линейное исполнение кода быстрее, но никто таком заниматься не будет. Если нужно выиграть пару милисекунд, то пиши на Си
|
12.08.2015 / 12:53 | | Bogdan-G Пользователь Сейчас: Offline
Имя: Богдан Откуда: Москва Регистрация: 13.02.2011
| Не успел отредактировать, перефразирую вопросы в посте выше. 1) Почему приложение потребляет больше памяти чем оно использует?(то есть память нужная приложению+память для ява-машины+память на GC+память на потоки) Не означает ли это утечку памяти как таковую? 2) Почему при изучении heapdump часто встречается что из 100% занятой памяти heap-ом в конкретном процессе занято какими либо объектами или классами составляет до 40%, а все остальное не иначе как промаркировано как null. Если это верно и 60% heap является незанятым приложению, то зачем эта память продолжает "висеть". 3) Какими способами можно сказать Windows что отдельная часть памяти больше процесс приложения не использует и его можно отдать обратно ОС?
Изменено Bogdan-G (12.08 / 12:54) (всего 1 раз) |
12.08.2015 / 12:56 | | Naik Пользователь Сейчас: Offline
Имя: %name% Регистрация: 14.03.2010
| Bogdan-G, выделяется сразу много памяти потому что выделение памяти ресурсоемкая операция. Выделяется наперед, так сказать. Есть всякие опции для запуска, можешь поэксперементировать, если интересно
|
12.08.2015 / 13:06 | | Bogdan-G Пользователь Сейчас: Offline
Имя: Богдан Откуда: Москва Регистрация: 13.02.2011
| Naik, я уже полгода экспериментирую, и мне интересно как во время работы приложения отдать память обратно ОС, а то выходит потом что сама windows забирает память(и судя по тестам, ту самую мертвую область) у приложения когда на уровне железа памяти уже не хватает. И при этом приложение, которое обделили(ява-приложение) продолжает нормально функционировать как будто ничего и не было. Что прямо говорит о том что берет оно больше чем нужно.
Вторя проблема, как ява-машина на это реагирует, если для выделения нового участка памяти выделяться из ОЗУ незанятый фрагмент памяти, то это означает накопление мертвого пространства которое ничто не будет использовать до перезапуска. Это в свою очередь говорит нам о плохой работе с памятью и не умение ее использовать экономно в угоду псевдо-скорости. На Си с этим проблем нет если правильно написать код, на яве то же так должно быть в теории, ибо написана она базово на том же языке, а раз интерпритатор(коверкаю да, может даже не то слово подставил) на др ЯП так себя ведет... это значит либо задумка(заказ) такая создателей либо не очень хорошее знание Си. При условии вины JVM в таком поведении.
Третья проблема, это накопление ошибок как в ява-машине так и в компиляторе/интерпритаторе, так и в самом проекте что приводит как снежный ком к нестабильности и ухудшению качества продукта и его работы в целом.
Изменено Bogdan-G (12.08 / 13:19) (всего 10 раз) |
12.08.2015 / 13:25 | | Bogdan-G Пользователь Сейчас: Offline
Имя: Богдан Откуда: Москва Регистрация: 13.02.2011
| ^ ПС Моя задача найти виновника торжества и попытаться хотя-бы помочь улучшить качество и стабильность продукта. Поэтому я ищу и задаю тут вопросы.
Изменено Bogdan-G (12.08 / 13:26) (всего 1 раз) |
12.08.2015 / 13:42 | | aNNiMON Супервизор Сейчас: Offline
Имя: Витёк Регистрация: 11.01.2010
| Bogdan-G, давай посмотрим на проблему немного под другим углом. TL;DR используй циклВариант 1. Множество if'ов.У тебя есть громадный исходник с кучей проверок: if (array[i++] == 0) System.out.println("Kek: " + i);
if (array[i++] == 0) System.out.println("Kek: " + i);
//...
if (array[i++] == 0) System.out.println("Kek: " + i);
Ты компилируешь его (долго компилируешь): javac Main.javaНаконец, получаешь .class файл: Label17450:
.line 527
17450: aload_2
17451: iload_3
17452: iinc 3 1
17455: iaload
17456: ifne Label17484
17459: getstatic java/lang/System/out Ljava/io/PrintStream;
17462: new java/lang/StringBuilder
17465: dup
17466: invokespecial java/lang/StringBuilder/<init>()V
17469: ldc "Kek: "
17471: invokevirtual java/lang/StringBuilder/append(Ljava/lang/String;)Ljava/lang/StringBuilder;
17474: iload_3
17475: invokevirtual java/lang/StringBuilder/append(I)Ljava/lang/StringBuilder;
17478: invokevirtual java/lang/StringBuilder/toString()Ljava/lang/String;
17481: invokevirtual java/io/PrintStream/println(Ljava/lang/String;)V
Теперь тебе надо запустить его: java MainИ вот тут в дело вступает JVM. Первым делом что она должна сделать с твоим исходником? Правильно, загрузить. Так как кода много, делать она будет это долго. Соответственно и память больше расходуется. Пока остановимся на этом и посмотрим Вариант 2. Цикл.Исходник while (i < size) {
if (array[i++] == 0) System.out.println("Kek: " + i);
}
Байт-код Label8:
.line 12
8: iload_3
9: sipush 10000
12: if_icmpge Label52
.line 13
15: aload_2
16: iload_3
17: iinc 3 1
20: iaload
21: ifne Label8
24: getstatic java/lang/System/out Ljava/io/PrintStream;
27: new java/lang/StringBuilder
30: dup
31: invokespecial java/lang/StringBuilder/<init>()V
34: ldc "Kek: "
36: invokevirtual java/lang/StringBuilder/append(Ljava/lang/String;)Ljava/lang/StringBuilder;
39: iload_3
40: invokevirtual java/lang/StringBuilder/append(I)Ljava/lang/StringBuilder;
43: invokevirtual java/lang/StringBuilder/toString()Ljava/lang/String;
46: invokevirtual java/io/PrintStream/println(Ljava/lang/String;)V
49: goto Label8
Label52: // выход из цикла
Что имеем? Маленький исходник, читабельность, быстрая загрузка класса на исполнение. Но это ещё не всё. Определение Stack Frames для второго варианта: ; append_frame (frameNumber = 0)
; frame_type = 254, offset_delta = 8
; frame bytes: 254 0 8 0 7 0 19 1
.stack
offset 8
locals Top
locals Object [I
locals Integer
.end stack
; same_frame (frameNumber = 1)
; frame_type = 43, offset_delta = 43
; frame bytes: 43
.stack
offset 52
locals Top
locals Object [I
locals Integer
.end stack
И оно же для варианта с if'ами: ; append_frame (frameNumber = 0)
; frame_type = 254, offset_delta = 42
; frame bytes: 254 0 42 0 7 0 19 1
.stack
offset 42
locals Top
locals Object [I
locals Integer
.end stack
; same_frame (frameNumber = 1)
; frame_type = 33, offset_delta = 33
; frame bytes: 33
.stack
offset 76
locals Top
locals Object [I
locals Integer
.end stack
...
; same_frame (frameNumber = 999)
; frame_type = 33, offset_delta = 33
; frame bytes: 33
.stack
offset 34008
locals Top
locals Object [I
locals Integer
.end stack
Не особо понимаю в Stack Frame, но как мне кажется, поскольку их здесь больше, то будет тратится время на их загрузку. Вывод: много сравнений не вариант, используй цикл. __________________
let live
Прикрепленные файлы: kek.zip (73.75 кб.) Скачано 18 раз |
12.08.2015 / 13:59 | | Naik Пользователь Сейчас: Offline
Имя: %name% Регистрация: 14.03.2010
| Цитата Bogdan-G: Naik, я уже полгода экспериментирую, и мне интересно как во время работы приложения отдать память обратно ОС, а то выходит потом что сама windows забирает память(и судя по тестам, ту самую мертвуюну так все правильно, выделяет много памяти, чтобы в процессе работы не выделять. Но когда памяти уже не хватает, то отдает лишнее. То же самое и в Android. Главное чтоб освобождалось вовремя.
|
12.08.2015 / 14:34 | | Askalite Пользователь Сейчас: Offline
Имя: Аскалайт Регистрация: 12.10.2011
| Цитата Bogdan-G: ^ ПС Моя задача найти виновника торжества и попытаться хотя-бы помочь улучшить качество и стабильность продукта. Поэтому я ищу и задаю тут вопросы.Цитата Naik: ну так все правильно, выделяет много памяти, чтобы в процессе работы не выделять. Но когда памяти уже не хватает, то отдает лишнее. То же самое и в Android. Главное чтоб освобождалось вовремя. Проблема в том, что JVM отдаёт память по запросу или по наполнению памяти другой java программы. Программы Windows не являются частью JVM, а значит не могут отправить запрос или регистрированны JVM. Windows программы "Считают" (хотя это в корне не верно), что память занята под JVM. В случае же с андроидом, Dalvik установлен по умолчанию и там не бывает утечек памяти. Зато есть утечки процессорного времени из-за низкой оптимизацией драйверов производителем под нативные библиотеки.
Изменено Ксакеп (13.08 / 06:46) (всего 1 раз) |
12.08.2015 / 14:46 | | Bogdan-G Пользователь Сейчас: Offline
Имя: Богдан Откуда: Москва Регистрация: 13.02.2011
| aNNiMON, спасибо за разъяснение, но я продолжу ковырять дальше, ибо кроме if,for есть и др функции в яве. Naik, выделяет много памятипотребляет 2, но взяло 100, чтобы в процессе работы не выделятьа в чем проблема делать это(повторно выделять и отдавать) во время работы? что то сильно мешает? то отдает лишнеев итоге windows сует 50%, того что забирает у процесса сидящего в ОЗУ, в swap и 50% оставшегося перманентно. Androidа это чудо инженерной мысли когда происходит java.lang.OutOfMemory: java heap space; частенько вешает всю систему, хотя это от прошивки к прошивке и от устройства к устройству. А так же этот феномен может повесить и windows. Главное чтоб освобождалось вовремя после этой операции приложение может требовать еще, но памяти то уже больше нету и либо приложение будет выгружено либо java.lang.OutOfMemory: java heap space и shutdown OS. А не очистить мертвую область или использовать повторно часть себя. "использовать повторно часть себя" - не официальная jvm, умеет так делать, но не сильно то и успешно, но толк уже есть чем падать за секунды не успев ничего сохранить потеряв данные, если пользователь то не страшно может быть(от ситуации к ситуации), а если в корпорации на главном сервере то это большие, куда большие потери. |
12.08.2015 / 17:53 | | Alexandr Пользователь Сейчас: Offline
Имя: Александр Откуда: Днепр Регистрация: 01.07.2012
| Вечер добрый. Возможно ли компилировать классы по отдельности? Например онлайн компилятором, где нет возможности загрузить весь проект.
|
Всего сообщений: 16875 Фильтровать сообщения Поиск по теме Файлы топика (794)
|