Вниз  Java-программирование (1-ые посты)
- 12.08.2015 / 12:50
Naik
  Пользователь

Naik 
Сейчас: Offline
Bogdan-G, очевидно линейное исполнение кода быстрее, но никто таком заниматься не будет. Если нужно выиграть пару милисекунд, то пиши на Си
- 12.08.2015 / 12:53
Bogdan-G
  Пользователь

Bogdan-G 
Сейчас: Offline
Не успел отредактировать, перефразирую вопросы в посте выше.
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
  Пользователь

Naik 
Сейчас: Offline
Bogdan-G, выделяется сразу много памяти потому что выделение памяти ресурсоемкая операция. Выделяется наперед, так сказать. Есть всякие опции для запуска, можешь поэксперементировать, если интересно
- 12.08.2015 / 13:06
Bogdan-G
  Пользователь

Bogdan-G 
Сейчас: Offline
Naik, я уже полгода экспериментирую, и мне интересно как во время работы приложения отдать память обратно ОС, а то выходит потом что сама windows забирает память(и судя по тестам, ту самую мертвую область) у приложения когда на уровне железа памяти уже не хватает. И при этом приложение, которое обделили(ява-приложение) продолжает нормально функционировать как будто ничего и не было. Что прямо говорит о том что берет оно больше чем нужно.

Вторя проблема, как ява-машина на это реагирует, если для выделения нового участка памяти выделяться из ОЗУ незанятый фрагмент памяти, то это означает накопление мертвого пространства которое ничто не будет использовать до перезапуска. Это в свою очередь говорит нам о плохой работе с памятью и не умение ее использовать экономно в угоду псевдо-скорости. На Си с этим проблем нет если правильно написать код, на яве то же так должно быть в теории, ибо написана она базово на том же языке, а раз интерпритатор(коверкаю да, может даже не то слово подставил) на др ЯП так себя ведет... это значит либо задумка(заказ) такая создателей либо не очень хорошее знание Си. При условии вины JVM в таком поведении.

Третья проблема, это накопление ошибок как в ява-машине так и в компиляторе/интерпритаторе, так и в самом проекте что приводит как снежный ком к нестабильности и ухудшению качества продукта и его работы в целом.

Изменено Bogdan-G (12.08 / 13:19) (всего 10 раз)
- 12.08.2015 / 13:25
Bogdan-G
  Пользователь

Bogdan-G 
Сейчас: Offline
^
ПС Моя задача найти виновника торжества и попытаться хотя-бы помочь улучшить качество и стабильность продукта. Поэтому я ищу и задаю тут вопросы.

Изменено Bogdan-G (12.08 / 13:26) (всего 1 раз)
- 12.08.2015 / 13:42
aNNiMON
  Супервизор

aNNiMON 
Сейчас: Offline
Bogdan-G, давай посмотрим на проблему немного под другим углом.

TL;DR используй цикл

Вариант 1. Множество if'ов.

У тебя есть громадный исходник с кучей проверок:
  1. if (array[i++] == 0) System.out.println("Kek: " + i);
  2. if (array[i++] == 0) System.out.println("Kek: " + i);
  3. //...
  4. if (array[i++] == 0) System.out.println("Kek: " + i);

Ты компилируешь его (долго компилируешь):
javac Main.java

Наконец, получаешь .class файл:
  1. Label17450:
  2.   .line 527
  3.   17450: aload_2
  4.   17451: iload_3
  5.   17452: iinc 3 1
  6.   17455: iaload
  7.   17456: ifne Label17484
  8.   17459: getstatic java/lang/System/out Ljava/io/PrintStream;
  9.   17462: new java/lang/StringBuilder
  10.   17465: dup
  11.   17466: invokespecial java/lang/StringBuilder/<init>()V
  12.   17469: ldc "Kek: "
  13.   17471: invokevirtual java/lang/StringBuilder/append(Ljava/lang/String;)Ljava/lang/StringBuilder;
  14.   17474: iload_3
  15.   17475: invokevirtual java/lang/StringBuilder/append(I)Ljava/lang/StringBuilder;
  16.   17478: invokevirtual java/lang/StringBuilder/toString()Ljava/lang/String;
  17.   17481: invokevirtual java/io/PrintStream/println(Ljava/lang/String;)V

Теперь тебе надо запустить его:
java Main

И вот тут в дело вступает JVM.

Первым делом что она должна сделать с твоим исходником? Правильно, загрузить.
Так как кода много, делать она будет это долго. Соответственно и память больше расходуется.

Пока остановимся на этом и посмотрим


Вариант 2. Цикл.

Исходник
  1. while (i < size) {
  2.     if (array[i++] == 0) System.out.println("Kek: " + i);
  3. }

Байт-код
  1. Label8:
  2.   .line 12
  3.   8: iload_3
  4.   9: sipush 10000
  5.   12: if_icmpge Label52
  6.   .line 13
  7.   15: aload_2
  8.   16: iload_3
  9.   17: iinc 3 1
  10.   20: iaload
  11.   21: ifne Label8
  12.   24: getstatic java/lang/System/out Ljava/io/PrintStream;
  13.   27: new java/lang/StringBuilder
  14.   30: dup
  15.   31: invokespecial java/lang/StringBuilder/<init>()V
  16.   34: ldc "Kek: "
  17.   36: invokevirtual java/lang/StringBuilder/append(Ljava/lang/String;)Ljava/lang/StringBuilder;
  18.   39: iload_3
  19.   40: invokevirtual java/lang/StringBuilder/append(I)Ljava/lang/StringBuilder;
  20.   43: invokevirtual java/lang/StringBuilder/toString()Ljava/lang/String;
  21.   46: invokevirtual java/io/PrintStream/println(Ljava/lang/String;)V
  22.   49: goto Label8
  23. Label52: // выход из цикла

Что имеем? Маленький исходник, читабельность, быстрая загрузка класса на исполнение.
Но это ещё не всё.

Определение Stack Frames для второго варианта:
  1. ; append_frame (frameNumber = 0)
  2. ; frame_type = 254, offset_delta = 8
  3. ; frame bytes: 254 0 8 0 7 0 19 1
  4. .stack
  5.   offset 8
  6.   locals Top
  7.   locals Object [I
  8.   locals Integer
  9. .end stack
  10. ; same_frame (frameNumber = 1)
  11. ; frame_type = 43, offset_delta = 43
  12. ; frame bytes: 43
  13. .stack
  14.   offset 52
  15.   locals Top
  16.   locals Object [I
  17.   locals Integer
  18. .end stack

И оно же для варианта с if'ами:
  1. ; append_frame (frameNumber = 0)
  2. ; frame_type = 254, offset_delta = 42
  3. ; frame bytes: 254 0 42 0 7 0 19 1
  4. .stack
  5.   offset 42
  6.   locals Top
  7.   locals Object [I
  8.   locals Integer
  9. .end stack
  10. ; same_frame (frameNumber = 1)
  11. ; frame_type = 33, offset_delta = 33
  12. ; frame bytes: 33
  13. .stack
  14.   offset 76
  15.   locals Top
  16.   locals Object [I
  17.   locals Integer
  18. .end stack
  19. ...
  20. ; same_frame (frameNumber = 999)
  21. ; frame_type = 33, offset_delta = 33
  22. ; frame bytes: 33
  23. .stack
  24.   offset 34008
  25.   locals Top
  26.   locals Object [I
  27.   locals Integer
  28. .end stack

Не особо понимаю в Stack Frame, но как мне кажется, поскольку их здесь больше, то будет тратится время на их загрузку.

Вывод: много сравнений не вариант, используй цикл.
__________________
 let live


Прикрепленные файлы:
kek.zip (73.75 кб.) Скачано 18 раз
- 12.08.2015 / 13:59
Naik
  Пользователь

Naik 
Сейчас: Offline
Цитата Bogdan-G:
Naik, я уже полгода экспериментирую, и мне интересно как во время работы приложения отдать память обратно ОС, а то выходит потом что сама windows забирает память(и судя по тестам, ту самую мертвую
ну так все правильно, выделяет много памяти, чтобы в процессе работы не выделять. Но когда памяти уже не хватает, то отдает лишнее. То же самое и в Android. Главное чтоб освобождалось вовремя.
- 12.08.2015 / 14:34
Askalite
  Пользователь

Askalite 
Сейчас: Offline
Цитата Bogdan-G:
^ ПС Моя задача найти виновника торжества и попытаться хотя-бы помочь улучшить качество и стабильность продукта. Поэтому я ищу и задаю тут вопросы.
Цитата Naik:
ну так все правильно, выделяет много памяти, чтобы в процессе работы не выделять. Но когда памяти уже не хватает, то отдает лишнее. То же самое и в Android. Главное чтоб освобождалось вовремя.
  Проблема в том, что JVM отдаёт память по запросу или по наполнению памяти другой java программы. Программы Windows не являются частью JVM, а значит не могут отправить запрос или регистрированны JVM. Windows программы "Считают" (хотя это в корне не верно), что память занята под JVM. В случае же с андроидом, Dalvik установлен по умолчанию и там не бывает утечек памяти. Зато есть утечки процессорного времени из-за низкой оптимизацией драйверов производителем под нативные библиотеки.

Изменено Ксакеп (13.08 / 06:46) (всего 1 раз)
- 12.08.2015 / 14:46
Bogdan-G
  Пользователь

Bogdan-G 
Сейчас: Offline
aNNiMON, спасибо за разъяснение, но я продолжу ковырять дальше, ибо кроме if,for есть и др функции в яве.
Naik,
выделяет много памятипотребляет 2, но взяло 100, :kul3:
чтобы в процессе работы не выделятьа в чем проблема делать это(повторно выделять и отдавать) во время работы? что то сильно мешает?
то отдает лишнеев итоге 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
  Пользователь

Alexandr 
Сейчас: Offline
Вечер добрый.
Возможно ли компилировать классы по отдельности? Например онлайн компилятором, где нет возможности загрузить весь проект.
Наверх  Всего сообщений: 16875
Фильтровать сообщения
Поиск по теме
Файлы топика (794)