Java силы для вызова моего деструктора C++ (JNI)

Код для VB.net

    Protected Sub rptDetails_ItemDataBound(ByVal sender As Object, ByVal e As System.Web.UI.WebControls.RepeaterItemEventArgs) Handles rptDetails.ItemDataBound    
      If e.Item.ItemType = ListItemType.AlternatingItem Or e.Item.ItemType = ListItemType.Item Then
        Dim lblA As Label = CType(e.Item.FindControl("lblA"), Label)
        lblA.Text = "Found it!"
      End If
    End Sub
9
задан Paul Morie 18 June 2009 в 21:23
поделиться

5 ответов

Вы не можете принудительно выполнить сборку мусора с помощью System.gc (). Также не гарантируется, что когда-либо будет запускаться сборщик мусора, например, если ваше приложение работает только в течение короткого времени, а затем ваш финализатор не запускается вообще (JVM не запускает его при выходе). Вы должны создать close () или destroy () или любую другую функцию для своего класса, и когда вы закончите использовать экземпляр этого класса, вызовите его, предпочтительно из блока finally, например.


MyClass x = null;
try{
    x = new MyClass();
    x.work();
} finally {
    if (x!=null)
        x.close();
}
7
ответ дан 4 December 2019 в 10:34
поделиться

Еще немного посмотрев код, созданный SWIG, я вижу, что люди SWIG на самом деле уже справились с этим - они добавляют для вас функцию delete (). Похоже, что и программист, и сборщик мусора тоже могут удалить объект.

3
ответ дан 4 December 2019 в 10:34
поделиться

По моему мнению, финализаторы Java в основном бесполезны и уж точно не заменяют деструкторы C ++. К сожалению, в Java нет замены C ++ RAII.

Не пытайтесь принудительно завершить завершение Java. Когда вы закончите с чем-то, все функции, которые избавятся от этого. Это все, что вы можете сделать.

5
ответ дан 4 December 2019 в 10:34
поделиться

Подобные проблемы являются причиной того, что C # выбрал шаблон IDisposable для детерминированного завершения.

Я предлагаю вам следовать тому же шаблону и адаптировать его для пользователей Java.

В своем классе C ++ создайте отдельный общедоступный метод, который удаляет ваши ресурсы. Назовите его close, или dispose, или что-то в этом роде.

Пусть ваш деструктор C ++ вызовет общедоступный метод и скажет управляемым / GC пользователям класса C ++, что они должны вызвать метод, чтобы избежать утечки памяти.

0
ответ дан 4 December 2019 в 10:34
поделиться

Если вы полагаетесь на то, что код метода finalize запускается в определенное время, вам необходимо пересмотреть свой подход. Проблема здесь в том, что вы не знаете, когда JVM вызовет finalize , поскольку вы не знаете, когда объект будет собран сборщиком мусора.

Одна вещь, которую вы должны учитывать, поскольку ваш класс будет повторно использоваться в других проектах, это то, что он ' Возможно, конечный пользователь может использовать экземпляр класса таким образом, что он не будет собираться или сборка мусора будет маловероятной, например, создание статической ссылки на экземпляр класса. Я думаю, что создание метода close или destroy - ваш самый безопасный способ гарантировать, что ресурсы, которые использует экземпляр класса C ++, связанный с вашим объектом Java, высвобождаются должным образом.

Поскольку повторное использование вызывает беспокойство, вы можете использовать деструктор C ++, чтобы проверить, были ли освобождены ресурсы, и вызвать тот же код, если их не было, например:

class MyThing {
  public:
    void close();
    ~MyThing();

  private:
    bool released = false;
};

void
MyThing::close() {
  // close logic here
  this->released = true;
}

MyThing::~MyThing() {
  if (!released) {
    this->close();
  }
}

Таким образом, ваш существующий Надеюсь, что код C ++ не претерпит значительных изменений, и вы можете гарантировать, что ваши ресурсы высвобождаются детерминированным образом в контексте собственного кода, выполняемого через JNI.

например, создание статической ссылки на экземпляр класса. Я думаю, что создание метода close или destroy - ваш самый безопасный способ гарантировать, что ресурсы, которые использует экземпляр класса C ++, связанный с вашим объектом Java, высвобождаются должным образом.

Поскольку повторное использование вызывает беспокойство, вы можете использовать деструктор C ++, чтобы проверить, были ли освобождены ресурсы, и вызвать тот же код, если их не было, например:

class MyThing {
  public:
    void close();
    ~MyThing();

  private:
    bool released = false;
};

void
MyThing::close() {
  // close logic here
  this->released = true;
}

MyThing::~MyThing() {
  if (!released) {
    this->close();
  }
}

Таким образом, ваш существующий Надеюсь, что код C ++ не претерпит значительных изменений, и вы можете гарантировать, что ваши ресурсы высвобождаются детерминированным образом в контексте собственного кода, выполняемого через JNI.

например, создание статической ссылки на экземпляр класса. Я думаю, что создание метода close или destroy - ваш самый безопасный способ гарантировать, что ресурсы, которые использует экземпляр класса C ++, связанный с вашим объектом Java, высвобождаются должным образом.

Поскольку повторное использование вызывает беспокойство, вы можете использовать деструктор C ++, чтобы проверить, были ли освобождены ресурсы, и вызвать тот же код, если их не было, например:

class MyThing {
  public:
    void close();
    ~MyThing();

  private:
    bool released = false;
};

void
MyThing::close() {
  // close logic here
  this->released = true;
}

MyThing::~MyThing() {
  if (!released) {
    this->close();
  }
}

Таким образом, ваш существующий Надеюсь, что код C ++ не претерпит значительных изменений, и вы можете гарантировать, что ваши ресурсы высвобождаются детерминированным образом в контексте собственного кода, выполняемого через JNI.

Я думаю, что создание метода close или destroy - ваш самый безопасный способ гарантировать, что ресурсы, которые использует экземпляр класса C ++, связанный с вашим объектом Java, высвобождаются должным образом.

Поскольку повторное использование вызывает беспокойство, вы можете использовать деструктор C ++, чтобы проверить, были ли освобождены ресурсы, и вызвать тот же код, если их не было, например:

class MyThing {
  public:
    void close();
    ~MyThing();

  private:
    bool released = false;
};

void
MyThing::close() {
  // close logic here
  this->released = true;
}

MyThing::~MyThing() {
  if (!released) {
    this->close();
  }
}

Таким образом, ваш существующий Надеюсь, что код C ++ не претерпит значительных изменений, и вы можете гарантировать, что ваши ресурсы высвобождаются детерминированным образом в контексте собственного кода, выполняемого через JNI.

Я думаю, что создание метода close или destroy - ваш самый безопасный способ гарантировать, что ресурсы, которые использует экземпляр класса C ++, связанный с вашим объектом Java, высвобождаются должным образом.

Поскольку повторное использование вызывает беспокойство, вы можете использовать деструктор C ++, чтобы проверить, были ли освобождены ресурсы, и вызвать тот же код, если их не было, например:

class MyThing {
  public:
    void close();
    ~MyThing();

  private:
    bool released = false;
};

void
MyThing::close() {
  // close logic here
  this->released = true;
}

MyThing::~MyThing() {
  if (!released) {
    this->close();
  }
}

Таким образом, ваш существующий Надеюсь, что код C ++ не претерпит значительных изменений, и вы можете гарантировать, что ваши ресурсы высвобождаются детерминированным образом в контексте собственного кода, выполняемого через JNI.

5
ответ дан 4 December 2019 в 10:34
поделиться
Другие вопросы по тегам:

Похожие вопросы: