Skip to content
Open
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
3 changes: 3 additions & 0 deletions .gitignore
Original file line number Diff line number Diff line change
Expand Up @@ -10,6 +10,9 @@
# Mobile Tools for Java (J2ME)
.mtj.tmp/

# vim swap files
*.swp

# Package Files #
*.jar
!gradle-wrapper.jar
Expand Down
Binary file removed .gradle/6.3/executionHistory/executionHistory.lock
Binary file not shown.
Binary file removed .gradle/6.3/fileChanges/last-build.bin
Binary file not shown.
Binary file removed .gradle/6.3/fileHashes/fileHashes.lock
Binary file not shown.
Empty file removed .gradle/6.3/gc.properties
Empty file.
Binary file removed .gradle/6.5/executionHistory/executionHistory.bin
Binary file not shown.
Binary file removed .gradle/6.5/executionHistory/executionHistory.lock
Binary file not shown.
Binary file removed .gradle/6.5/fileChanges/last-build.bin
Binary file not shown.
Binary file removed .gradle/6.5/fileHashes/fileHashes.bin
Binary file not shown.
Binary file removed .gradle/6.5/fileHashes/fileHashes.lock
Binary file not shown.
Empty file removed .gradle/6.5/gc.properties
Empty file.
Binary file removed .gradle/buildOutputCleanup/buildOutputCleanup.lock
Binary file not shown.
2 changes: 0 additions & 2 deletions .gradle/buildOutputCleanup/cache.properties

This file was deleted.

Binary file removed .gradle/checksums/checksums.lock
Binary file not shown.
Empty file removed .gradle/vcs-1/gc.properties
Empty file.
3 changes: 0 additions & 3 deletions .idea/.gitignore

This file was deleted.

10 changes: 0 additions & 10 deletions .idea/compiler.xml

This file was deleted.

18 changes: 0 additions & 18 deletions .idea/gradle.xml

This file was deleted.

20 changes: 0 additions & 20 deletions .idea/jarRepositories.xml

This file was deleted.

7 changes: 0 additions & 7 deletions .idea/misc.xml

This file was deleted.

6 changes: 0 additions & 6 deletions .idea/vcs.xml

This file was deleted.

25 changes: 13 additions & 12 deletions README.md
Original file line number Diff line number Diff line change
@@ -1,15 +1,16 @@
# Примеры для курса "Разработчик Java" в OTUS
Написать приложение, которое следит за сборками мусора и пишет в лог количество сборок каждого типа (young, old) и время которое ушло на сборки в минуту.

Группа 2020-09
Добиться OutOfMemory в этом приложении через медленное подтекание по памяти (например добавлять элементы в List и удалять только половину).

### Преподаватели
Сергей Петрелевич<br>
Стрекалов Павел<br>
Александр Оруджев<br>
Вячеслав Лапин<br>
Виталий Куценко<br>
Дмитрий Коган
Настроить приложение (можно добавлять Thread.sleep(...)) так чтобы оно падало с OOM примерно через 5 минут после начала работы.

Студент:
Kashapov Renat (Кашапов Ренат)<br>
renat.kashapov@gmail.com
Собрать статистику (количество сборок, время на сборки) по разным GC.

!!! Сделать выводы !!! ЭТО САМАЯ ВАЖНАЯ ЧАСТЬ РАБОТЫ: Какой gc лучше и почему?

Выводы оформить в файле Сonclusions.md в корне папки проекта. Результаты измерений сведите в таблицу.

Попробуйте провести этот эксперимент на небольшом хипе порядка 256Мб, и на максимально возможном, который у вас может быть.

Критерии оценки:
Система оценки максимально соответсвует привычной школьной: 3 и больше - задание принято (удовлетворительно). ниже - задание возвращается на доработку.
51 changes: 51 additions & 0 deletions hw04-GCCompare/Conclusions.md
Original file line number Diff line number Diff line change
@@ -0,0 +1,51 @@
Запсукал тест из командной строки командой:

time java -Xms48m -Xmx48m -Xlog:gc=debug:file=./logs/gc-%p-%t.log:tags,uptime,time,level -XX:+UseParallelGC -cp hw04-GCCompare/build/classes/java/main GCCompare

Получил такие результаты выполнения по времени:

Usage|Serial|Parallel|G1|Z
---|---|---|---|---
real|m9.568s|1m42.697s|49m5.777s|24m5.742s
user|8m3.852s|1m40.046s|48m24.503s|23m43.360s
sys|0m0.168s|0m0.076s|0m16.451s|0m2.176s

Для логов получил такие результаты:

Parameter|Serial|Parallel|G1|Z
---|---|---|---|---
Young (кол-во сборок)|56.267ms (8)|125.543ms (8)|-|-
Old(Full) (кол-во сборок)|692.647ms (9)|658.036ms (7)|-|-
Total (кол-во сборок)|749.274ms (17)|783.579ms (15)|-|-

_Для выделяемого объёма памяти 56Мб G1 проработала более 80 минут, после чего программа была прервана. Поэтому сравнение велось на объёме память 48 мб_

Вывод: для Debian с 2 Гб памяти и максимальным возможным значением 494 Мб для HeapSize наиболее производительными будет Parallel.

При использовании Long вместо Date результаты по времени следующие:

Usage|Serial|Parallel|G1|Z
---|---|---|---|---
real|4m42.855s|1m45.182s|41m58.634s|18m35.383s
user|4m40.456s|1m43.557s|41m30.208s|18m24.164s
sys|0m0.088s|0m0.056s|0m11.325s|0m0.944s

Разница заметна, но не существенная. Однако это натолкнуло меня на наличие взаимосвязи между размером (атомарного) объекта и производительностью программы, обуславливаемой выбором GC.
В программу были внесены изменения (вместо объектов Long/Date в ArrayList начал заносить различные массивы int), результаты помещены в сводную таблицу (тестирование велось на выделенном объёме 494MB):

Usage|Serial|Parallel|G1|Z
---|---|---|---|---
int[256]|21.235s(466607)|10.222s(311071)|29.222s(466607)|122.573s(466607)
int[128]|43.598s(699911)|42.027s(699911)|99.843s(699911)|346.264s(699911)
int[64]|346.264s(1574801)|103.634s(1049867)|2008.708s(1574801)|5109.768s(1574801)

Таким образом время работы (на фиксированном выделенном объёме памяти) явно зависит от атомарного размера объекта, хотя мне более объективной видится зависимость от общего числа объектов в программе (в скобках приведены максимальные значения размеров ArrayList перед удалением половины объектов, при которых ещё не был достигнут OOM).
На моей машине наиболее оптимальным видится использование ParallelGC с точки зрения времени исполнения программы. Другое дело с точки зрения падения или достижения наибольшего числа объектов в ArrayList (по сути качество работы GC). ParallelGC в 2-х случах из 3-х не достиг показателей остальных GC. По совокупности обоих факторов на моей машине лучшим видится SerialGC.

Обработка логов для программы с использованием массивов int[128] (этого размера опытного массива удалось достичь всем GC) отражена в таблице:

Parameter|Serial|Parallel|G1|Z
---|---|---|---|---
Young (кол-во сборок)|212.054ms (7)|357.272ms (6)|-|-
Old(Full) (кол-во сборок)|1497.610ms (10)|1806.858ms (18)|-|-
Total (кол-во сборок)|1709.664ms (17)|2164.130ms (24)|-|-
14 changes: 14 additions & 0 deletions hw04-GCCompare/build.gradle
Original file line number Diff line number Diff line change
@@ -0,0 +1,14 @@
plugins {
id 'java'
}

group 'ru.otus'
version '1.0-SNAPSHOT'

repositories {
mavenCentral()
}

dependencies {
testCompile group: 'junit', name: 'junit', version: '4.12'
}
28 changes: 28 additions & 0 deletions hw04-GCCompare/src/main/java/GCCompare.java
Original file line number Diff line number Diff line change
@@ -0,0 +1,28 @@
import java.util.ArrayList;
import java.util.List;

/*
-Xms48m -Xmx48m -Xlog:gc=debug:file=./logs/gc-%p-%t.log:tags,uptime,time,level -XX:+UseSerialGC
-XX:+UseSerialGC (<default>)
-XX:+UseParallelGC
-XX:+UseG1GC
-XX:+UnlockExperimentalVMOptions -XX:+UseZGC
*/

public class GCCompare {
static final int ARRAY_SIZE = 64;
public static void main(String ... args){
List<int[]> intArrayList = new ArrayList<>();
intArrayList.add(new int[ARRAY_SIZE]);
while (true){
int currentSize = intArrayList.size();
System.out.println("currentSize is " + currentSize);
for (int i=currentSize-1;i>currentSize/2;i--){
intArrayList.remove((int) (Math.random()*intArrayList.size()));
}
for (int i = 0; i < currentSize; i++) {
intArrayList.add(new int[ARRAY_SIZE]);
}
}
}
}
1 change: 1 addition & 0 deletions settings.gradle
Original file line number Diff line number Diff line change
@@ -1,2 +1,3 @@
rootProject.name = 'otus_hw'
include 'hw04-GCCompare'

5 changes: 0 additions & 5 deletions src/main/java/A.java

This file was deleted.