Ну, тут є кілька питань в одному!
1 - Як управляються недовговічні об’єкти?
Як було сказано раніше, JVM може прекрасно справлятися з величезною кількістю короткоживучих об'єктів, оскільки це відповідає гіпотезі слабкого покоління .
Зауважте, що ми говоримо про об'єкти, які дійшли до основної пам'яті (купи). Це не завжди так. Багато створених вами об'єктів навіть не залишають реєстру процесора. Наприклад, розглянемо це для циклу
for(int i=0, i<max, i++) {
// stuff that implies i
}
Не будемо думати про розгортання циклу (оптимізація, яку JVM сильно виконує у вашому коді). Якщо max
вона дорівнює Integer.MAX_VALUE
, виконанню циклу може знадобитися певний час. Однак i
змінна ніколи не уникне циклу блоку. Тому JVM поміщає цю змінну в регістр процесора, регулярно збільшуючи її, але ніколи не відсилає її в основну пам'ять.
Отже, створення мільйонів об’єктів не є великою справою, якщо вони використовуються лише локально. Вони будуть мертвими до зберігання в Ідені, тому GC навіть не помітить їх.
2 - Чи корисно зменшити накладні витрати GC?
Як завжди, це залежить.
По-перше, ви повинні ввімкнути журнал GC, щоб мати чітке уявлення про те, що відбувається. Ви можете ввімкнути це за допомогою -Xloggc:gc.log -XX:+PrintGCDetails
.
Якщо ваша програма витрачає багато часу на цикл GC, тоді, так, налаштуйте GC, інакше це може бути не дуже вартим.
Наприклад, якщо у вас є молодий GC кожні 100 мс, який займає 10 мс, ви проводите 10% свого часу в ГК, і у вас є 10 колекцій в секунду (що становить велику оцінку). У такому випадку я б не витрачав часу на налаштування GC, оскільки ті 10 GC / s все ще будуть там.
3 - Певний досвід
У мене була схожа проблема з додатком, який створював величезну кількість даного класу. У журналах GC я помітив, що швидкість створення додатку становила близько 3 Гб / с, що занадто багато (давай ... 3 гігабайта даних щосекунди ?!).
Проблема: Занадто багато частих ГК, викликаних занадто великою кількістю об'єктів, що створюються.
У своєму випадку я приєднав профайлер пам'яті і помітив, що клас представляє величезний відсоток усіх моїх об’єктів. Я простежив моменти, щоб дізнатися, що цей клас був в основному парою булевих, загорнутих в об'єкт. У цьому випадку було доступно два рішення:
Переробіть алгоритм, щоб я не повертав пару булевих, але натомість у мене є два методи, які повертають кожен булевий окремо
Кешуйте об’єкти, знаючи, що існували лише 4 різних екземпляри
Я вибрав другий, оскільки він найменше вплинув на додаток і його було легко ввести. Потрібно було кілька хвилин, щоб поставити завод із кешем, не захищеним від потоку (безпека потоку мені не потрібна, оскільки в кінцевому підсумку у мене буде лише 4 різні екземпляри).
Швидкість розподілу знизилася до 1 ГБ / с, а також частота молодих ГК (розділена на 3).
Сподіваюся, що це допомагає!