2016-09-29 2 views
1

Я использую инъекцию зависимостей (DI) внутри приложения RCP Eclipse. У меня есть много классов, которые выполняют код, аналогичный ниже:Утечка памяти/ContextInjectionFactory/IEclipseContext

public class SomeClass { 
    @Inject 
    private IEclipseContext context; 

    private SomeObject void someMethod(){ 
     SomeObject someObject = 
      ContextInjectionFactory.make(SomeObject.class, context); 
     // Do stuff with someObject 
    } 
} 

Когда я контролировать приложение с помощью jvisualvm, я замечаю, есть утечка памяти из-за этого. Объект EclipseContext продолжает расти, пока в конце концов не закончится память.

Если я делаю следующее, утечка памяти уходит:

public class SomeClass { 
    @Inject 
    private IEclipseContext context; 

    private SomeObject void someMethod(){ 
     IEclipseContext childContext = context.createChild(); 
     SomeObject someObject = 
      ContextInjectionFactory.make(SomeObject.class, childContext); 
     childContext.dispose(); 
     // Do stuff with someObject 
    } 
} 

Я не видел никакой документации, которая поддерживает делает мой обходной путь. Есть ли какие-либо отрицательные побочные эффекты для удаления childContext после создания класса? Есть ли лучший подход при использовании CIF, с которым я не сталкивался?

Для чего это стоит, мой код имеет много классов, некоторые из которых аннотируются с @Singleton/@Creatable. Я не уверен, что это будет осуществляться с помощью расположенного родительского контекста.

Спасибо!

+0

Я не видел никаких сообщений о наличии утечки, и я не видел этого в своем коде. –

+0

Да, это определенно странно. Единственное отличие в моем коде - это то, что показано выше. Я создаю много объектов, большинство из которых уничтожаются, когда они больше не нужны. В течение нескольких дней я замечаю, что в главном контексте есть миллионы ссылок на объекты, и он растет, пока я не получу ошибку памяти. Если я сделаю обходной путь, все будет хорошо. Знаете ли вы о каком-либо негативном воздействии с помощью обходного пути? – ekjcfn3902039

+0

Если что-либо, что вы делаете с дочерним контекстом, вставляет IEclipeContext, он в конечном итоге обратится к удаленному контексту, если он попытается получить к нему доступ позже. Это затрудняет отладку ошибок. Вы знаете, какое поле в классе EclipseContext хранит все эти ссылки? –

ответ

2

При использовании инъекции для установки полей в классе, как это:

public class Test 
{ 
    @Inject 
    private StatusReporter rep; 
    @Inject 
    private IEventBroker broker; 


    public Test() 
    { 
    } 
} 

Eclipse, должен отслеживать каждое поле, которое было введено, чтобы он мог инжектирует поле, если значение в изменении контекста Eclipse. Это включает в себя создание объектов TrackableComputationEx‌​t и ‌​ContextInjectionList‌​ener объектов для каждого введенного поля.

Если вместо этого Вы вводите значения в конструкторе, как это:

public class Test 
{ 
    private StatusReporter rep; 
    private IEventBroker broker; 

    @Inject 
    public Test(StatusReporter rep, IEventBroker broker) 
    { 
    this.rep = rep; 
    this.broker = broker; 
    } 
} 

Eclipse, не имеет никакой необходимости отслеживать Конструктора инъекции, так что эти объекты не создаются (но вы также не получите какие-либо обновления, если в контексте значения изменены).

Тестирование этого объекта все еще кажется одним созданным объектом отслеживания внутреннего использования.

+0

Странно, что никто не упомянул то же самое, что и я, так как вижу много кода, используя полевые инъекции против инъекций конструктора. Убирают ли объекты отслеживания после того, как класс больше не используется? Если у меня есть коллекция объектов и очистить коллекцию, уходите ли ссылки отслеживания? Я предполагаю (по количеству экземпляров, которые я видел), что с полевыми инъекциями у них нет (даже если бы я их ожидал) – ekjcfn3902039

+0

Ну, у Java нет способа отслеживания, когда что-то «уходит» (если нет некоторых WeakReferences где-то я пропустил), так что, вероятно, нет. Они, вероятно, висят, пока контекст не будет удален. Но этот код очень сложный и трудно читаемый (как обычно). Я думаю, что большинство людей используют только инъекции на ограниченном количестве объектов пользовательского интерфейса, поэтому не ударились об этом. –