java-скриптинг в mozilla rhino и проблема с управлением памятью

#java #javascript #scripting #rhino

#java #javascript #скриптинг #rhino

Вопрос:

Я создаю javascript api, который будет вызывать некоторые объекты Java с помощью mozilla rhino.

Все хорошо, однако я хочу избежать неограниченного зацикливания, которое может замедлить работу моего Java-приложения.

например (в javascript):

 while(true) doSomething(); // doSomthing will call a method in java
  

В современных браузерах через определенное время появляется ошибка, сообщающая, что скрипт замедляет работу приложения, и если я хочу продолжить и остановить скрипт.

Я хочу реализовать это в своем Java-приложении, если это возможно, но я не знаю как. Единственное решение, о котором я могу подумать, это подсчитать количество методов, вызываемых в секунду, и, если это огромное число, остановить скрипт. У вас есть какие-либо другие идеи?

Комментарии:

1. Я чего-то не понимаю — вам действительно нужно постоянно вызывать этот метод? Или вы пытаетесь реализовать какой-то механизм тайм-аута, который отменяется doSomething() , если он выполняется более N секунд?

2. @matt b Часть кода javascript не будет реализована мной. это будет сделано сторонними разработчиками. Чего я хочу, так это не предоставлять им полную свободу, поскольку мои Java-приложения на самом деле основаны на сервере, и я не хочу замедлять работу своей машины.

Ответ №1:

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

 while (true) {
    i  ;
}
  

Я думаю, что вам нужно, это observeInstructionCount(). Также посмотрите обсуждение здесь — некоторые вещи, которые они обсуждают, выглядят немного сомнительно, но это может вам помочь.

Ответ №2:

Если вы можете сделать приложение многопоточным, вы могли бы создать новый поток, обрабатывающий каждый вызов из javascript. в начале потока вы записываете время запуска и создаете некоторую логику тайм-аута, соответствующую этому.

     public void doJavaScript() {
      final long start = System.currentTimeMillis();
      final long timeout = 1000;
      new Thread(){
          @Override
          public void run() {
             while ((start   timeout) < System.currentTimeMillis()) {
                ... do work ...
             }
          }
      }.start();
    }