ПЕРЕЛІК ДИСЦИПЛІН:
  • Адміністративне право
  • Арбітражний процес
  • Архітектура
  • Астрологія
  • Астрономія
  • Банківська справа
  • Безпека життєдіяльності
  • Біографії
  • Біологія
  • Біологія і хімія
  • Ботаніка та сільське гос-во
  • Бухгалтерський облік і аудит
  • Валютні відносини
  • Ветеринарія
  • Військова кафедра
  • Географія
  • Геодезія
  • Геологія
  • Етика
  • Держава і право
  • Цивільне право і процес
  • Діловодство
  • Гроші та кредит
  • Природничі науки
  • Журналістика
  • Екологія
  • Видавнича справа та поліграфія
  • Інвестиції
  • Іноземна мова
  • Інформатика
  • Інформатика, програмування
  • Юрист по наследству
  • Історичні особистості
  • Історія
  • Історія техніки
  • Кибернетика
  • Комунікації і зв'язок
  • Комп'ютерні науки
  • Косметологія
  • Короткий зміст творів
  • Криміналістика
  • Кримінологія
  • Криптология
  • Кулінарія
  • Культура і мистецтво
  • Культурологія
  • Російська література
  • Література і російська мова
  • Логіка
  • Логістика
  • Маркетинг
  • Математика
  • Медицина, здоров'я
  • Медичні науки
  • Міжнародне публічне право
  • Міжнародне приватне право
  • Міжнародні відносини
  • Менеджмент
  • Металургія
  • Москвоведение
  • Мовознавство
  • Музика
  • Муніципальне право
  • Податки, оподаткування
  •  
    Бесплатные рефераты
     

     

     

     

     

     

         
     
    Java: Управління ресурсами
         

     

    Інформатика, програмування

    Java: Управління ресурсами.

    Як я помітив, багато, що починають програмувати на Java, не зовсім чітко уявляють собі, як варто управляти ресурсами на цій мові. У даній статті я спробував викласти своє бачення на цей аспект програмування.

    Що може, а чого не може GC.

    Одним з особливостей мови Java є автоматичне прибирання сміття - горезвісний Garbage Collector (скорочено - GC). GC - це фоновий процес, який займається пошуком і звільненням невикористовуваних об'єктів. Багато списів було зламано в дискусіях, добре це чи погано, причому суттєві аргументи є як у прихильників, так і у противників цієї технології. Але я не про це. Приймемо існування GC як даність і розглянемо особливості програмування в даному середовищі.

    Одним із наслідків наявності GC (і відсутність розміщення об'єктів в стеку) є відсутність деструкторів, аналогічним існуючих в C + + - автоматично планування для для знищення об'єктів щодо виходу з області видимості. Замість них є інші механізми, які дозволяють домогтися того ж самого.

    Іншим наслідком є необхідність стежити за посиланнями на об'єкти, тому як GC саме за наявності посилання на об'єкт визначає його потрібність. Для можливості управління строгістю посилань у JDK 1.2 було введено новий пакет java.lang.ref, класи якого дозволяє створювати так звані "слабкі" посилання на об'єкти. Це особливо корисно для реалізації кешування об'єктів.

    Начитавшись рекламних статей, може здатися, що очищенням ресурсів взагалі не варто займатися - все зробить GC. Тут важливо розуміти, що в поняття ресурсів входить не лише оперативна пам'ять, але так само і багато іншого. Наприклад - відкриті файли, сокети, ResultSet-и і Statement-и в JDBC, і т.д. З очищенням пам'яті GC в останніх JVM справляється досить непогано, але звільнення інших ресурсів, як правило, не можна робити асинхронно. В іншому випадку легко отримати так звані "плаваючі" помилки, які то з'являються, то зникають.

    Над розробкою алгоритму роботи GC досить довго корпіли розробники, так що іноді його поведінка може здатися дещо дивним. Зокрема, він може звільняти об'єкти в довільному порядку, ніяк не пов'язаний з порядком їх створення або очищення останніх посилань на них. Так само, для прикладу, у JDK 1.3, GC починає звільняти об'єкти лише тоді, коли поточний пул пам'яті заповнюється. При цьому одночасно, цей пул розширюється, поки не дійде до заданого верхнього ліміту. Одночасно враховується час останнього доступу і розмір об'єкта. І т.д. і т.п.

    За замовчуванням верхній ліміт пулу залежить від системи. В JDK 1.3 він дорівнює 64 мегабайтам. У деяких випадках краще знизити цю планку, особливо коли на машині пам'яті не дуже багато - тим самим програма швидше дійде до цього ліміту і почне використовувати пам'ять повторно.

    Більшість JVM не віддають назад системі пам'ять, що вони забрали під пул. Я знаю тільки одну JVM, яка це робить - це Microsoft JVM. Всі інші хапають до зазначеного ліміту.

    деструкторів немає. А що замість?

    Багато програмісти (особливо тільки що пересів з C + +), бачать заміну деструкторів у вигляді методів finalize. Це не є правильно. По-перше, цей метод не викличеться, поки на об'єкт є посилання. Немає гарантії, що він викличеться тоді, коли вам це потрібно. Він може взагалі ніколи не викликала. Є, звичайно, метод System.runFinalizersOnExit (), але він вже давно deprecated через можливі deadlock-ів. Як слушно зауважив Bruce Eckel в чудовій книжці Thinking in Java метод finalize варто використовувати тільки для того, щоб звільнити пам'ять (або інший, не дуже критичний ресурс), виділену в native методах. Для інших же ресурсів слід додати явний виклик методу очищення ресурсів (він може називатися по-різному - close, dispose, cleanup, і т.д.), всередині конструкції finally. Всередині finally - для того, щоб не прогавити якесь виключення. Приклад типових конструкцій:

    OutputStream out = new FileOutputStream (...);

    try

    (

    ...

    )

    finally (out.close ();)

    PreparedStatement stmt = ...;

    try

    (

    stmt.setInt (1 ,...);

    ResultSet rs = stmt.executeQuery ();

    try

    (

    ...

    )

    finally (rs.close ();)

    )

    finally (stmt.close ();)

    Якщо Ви будете писати програми в такому стилі, то багато проблем уникнути стороною - повірте, я вже наступав на ці граблі. :-)

    Memory Leak в Java і як з

    Здавалося б - які можуть бути Memory Leak (витоки пам'яті), коли є GC. Але, тим не менше, вони можливі. Ці витоку відрізняються за своїм походженням від витоків в C/C + + (таких в Java взагалі бути не може, за винятком можливих помилок у JVM, але цей варіант ми тут не розглядаємо). Вони виникають через забутих посилань.

    Наприклад - В GUI часто використовується механізм слухачів (Listener-ів). Це коли одна об'єкт реєструється в іншому об'єкті для зворотного дзвінка з настанням якого-небудь події. Проблема тут може бути один - якщо Ви забудете разрегістріровать об'єкт, коли він стає непотрібним. При цьому він залишиться бовтатися в списку, ну і GC, зрозуміло, не буде видаляти цей об'єкт, поки не прийде час видалити об'єкт зі списком (а цього може і не статися до завершення програми).

    В результаті - список буде пухнути, пухнути, програма працює все повільніше і повільніше, і, врешті-решт, вилітає OutOfMemoryError.

    Відстежити такий сценарій можна за допомогою спеціальних програм - профайлеров. Найкращі відомі на даний момент - JProbe і OptimizeIt.

    Боротися з цими речами досить просто - треба не забути разрегістріроваться. Якщо Ви впевнені, що об'єкт-слухач видаляється разом з об'єктом - джерелом подій (наприклад, коли вони обидва сидять усередині діалогу), то цього робити не потрібно - GC сам з ними розбереться.

    Кешування об'єктів.

    Кешування об'єктів застосовується для підвищення продуктивності. Коли об'єкт змінюється рідко (або взагалі не змінюється в процесі роботи програми), то часто корисно прочитати його один раз, і запам'ятати на нього посилання. Але посилання - це протиріччя між алгоритмом роботи GC, а значить, цей об'єкт ніколи не буде зібраний GC (навіть якщо він більше не потрібний). Іноді це великого значення не має (пам'яті багато, або всі об'єкти потрібні дуже часто), але частіше бажано все-таки мати можливість почистити невживані об'єкти.

    В JDK 1.2 для цих цілей було додано декілька класів, найбільш цікаві з них - WeakReference і SoftReference. Weak ( "слабка") посилання буде очищена, якщо на об'єкт немає більш "сильних" посилань і об'єкт попався під руку GC. Soft ( "м'яке") посилання буде очищена, якщо на об'єкт немає звичайних посилань, і, до об'єкту не доступуЛ за цим посиланням певний час (евристичний розраховується в залежності від поточного оточення). Для кешування найкраще підходять посилання типу Soft, тому що в них враховується частота звернення до об'єкта.

    Безпосередньо користуватися цими посиланнями не дуже зручно, краще написати контейнер з їх використанням. Ось, наприклад реалізація класу SoftHashtable:

    import java.lang.ref.SoftReference;

    import java.util.Hashtable;

    public class SoftHashtable extends Hashtable

    (

    public SoftHashtable () ()

    public Object put (Object key, Object obj)

    (

    SoftReference ref = (SoftReference) super.put (key, new SoftReference (obj ));

    if (ref == null) return null;

    return ref.get ();

    )

    public Object get (Object key)

    (

    SoftReference ref = (SoftReference) super.get (key);

    if (ref == null) return null;

    return ref.get ();

    )

    public Object remove (Object key)

    (

    SoftReference ref = (SoftReference) super.remove (key);

    if (ref == null) return null;

    return ref.get ();

    )

    )

    Цей клас є неповним, при бажанні Ви можете перекрити інші методи Hashtable. За допомогою цього класу Ви вже можете легко організувати свій кеш об'єктів:

    private static Hashtable objCache = new SoftHashtable ();

    public SuperObject getObject (String key)

    (

    SuperObject o = (SuperObject) objCache.get (key);

    if (o == null)

    (

    o = loadObject (key);

    objCache.put (key, o);

    )

    return o;

    )

    Таким чином, якщо GC виявить, що пам'яті залишилося мало, а в кеші бовтаються об'єкти, до яких давно ніхто не звертався, він зможе їх почистити.

    Список літератури

    Для підготовки даної роботи були використані матеріали з сайту http://people.comita.spb.ru/

         
     
         
    Реферат Банк
     
    Рефераты
     
    Бесплатные рефераты
     

     

     

     

     

     

     

     
     
     
      Все права защищены. Reff.net.ua - українські реферати ! DMCA.com Protection Status