oracle / graaljs

GraalJS – A high-performance, ECMAScript compliant, and embeddable JavaScript runtime for Java
https://www.graalvm.org/javascript/
Universal Permissive License v1.0
1.83k stars 192 forks source link

Using graal as a multi-threading #635

Open kingkong3 opened 2 years ago

kingkong3 commented 2 years ago

Hello, I'm replacing java's script engine with graal from Nashorn.

However, unlike Nashorn, graal does not support multi-threading, so the following methods were used To briefly explain my code, :

  1. When initializing the server, create a specific number of script engines and add them to the queue
Context newEngine = Context.newBuilder("js").option("engine.WarnInterpreterOnly", "false").allowAllAccess(true).allowHostClassLookup(className -> true).build();

ScriptEngineQueue.getInstance().add(newEngine );
  1. Then poll the script engine and evaluate the script in Java.
Context engine = ScriptEngineQueue.getInstance().poll();
engine.eval("js", script);
  1. Add the evaluation script engine back to the queue.

ScriptEngineQueue.getInstance().add(engine);

It takes up quite a lot of resources to create an engine, so I've created it in advance. About 200 script engines are generated, and memory leaks are suspected in this situation, so I would like to ask if there is any problem in using them with the above usage.

Please reply. Thank you.

oubidar-Abderrahim commented 2 years ago

cc @iamstolis

lemanschik commented 1 year ago

You need to use something like vertx to be more clear this is what you want:

@oubidar-Abderrahim @iamstolis @kingkong3

https://reactiverse.io/es4x/

the es4x java package is a JS Context Factory linking each context with a vertx eventbus as IPC Replacement.

caoccao commented 1 year ago

I'm also interested in this pooling design. As GraalJS GC is integrated with the JVM GC, does a GC of a specific ScriptEngine generate impacts to the rest of engines in the pool?

lemanschik commented 1 year ago

@caoccao The JS Engine has no real own GC Everything is the JVM GC if you tune that it will have effects on the JS GC only when you use graal-node then you will use libuv and the NodeJS GC. GC is nothing that is JS Specific it comes always from the Engine that Embeddeds JS. JS is always only the single context everything else comes from the outside.

And you can even avoid GC in JS If you simple do not assign as much.

caoccao commented 1 year ago

Thank @lemanschik for the detailed explanation.

That confirms my concern: the script engines in GraalJS are not completely isolated as they share the same GC. In some critical situations, the GC intensive script engines might impact the other CPU (real-time) intensive script engines.

There are other solutions which have V8 embedding in JVM with standalone GC. That allows fine-grain controls over the individual V8 instances to avoid the case above.

Hope this makes sense. I'm not here to discredit GraalJS. I'm just curious in the tech detail and the implications behind the high level design.

lemanschik commented 1 year ago

@caoccao your going highly theoretical here i could now explain in detail while this will have no effect for you but we make it short simple code and benchmark and you will see there are no issues with that. You did read a few papers or docs that did confuse you a bit. I am Chromium Platform Architectural Engineer. I have knowledge about the JVM and its internals V8 and the Internals as also Many other Engines Systems (CPU/RAM/BUS) things. In Theory your correct but the engine authors did take care of such things.

in Real world nothing will be unresponsive or something else measurable will have impact to your software

lemanschik commented 1 year ago

@caoccao if you want to mix Software GraalVM is great for that and if you thought that your code runs in the engine no matter which name then your wrong. When you compile a GraalVM Project via Substrate VM to binary you get ASM so not your code anymore its highly optimized.

Also in the browser the result of your JS is Assembler it does not feel and look like that but that's what happens.

caoccao commented 1 year ago

Well, now the topic seems to move to AOT. I'm fine with everything changed/optimized in AOT, but JS interoperability is lost in AOT. In quite a lot of scenarios, JS interoperability is the key feature that blocks folks from moving towards AOT. Please correct me if I'm wrong.

lemanschik commented 1 year ago

@caoccao your partial wrong you did forget the fact that you can compile the whole JS Engine AOT you see a example with graal-node. And even if you do not use AOT you can fine tune the JVM with over 1k parameters but you should dig into that when the time and need did come up and that will not happen.

caoccao commented 1 year ago

I'm confused about the definition of right or wrong. I'm here doubting the unified GC vs. isolated GC. I'm told unified GC could achieve all what the isolated GC could do with 0 side effects. If I disagree with that, I'm wrong. Hope that's not what is happening here.

lemanschik commented 1 year ago

@caoccao it is because your not aware of GC Implementation details for example GraalVM ships with multiple once that you can switch to be more exact the JVM in this case (HotSpot) does so and there are even GC less JVM's but as said before you will understand all that once it comes to real life.

In Real life languages like Rust also have some kind of GC and they also stop the world thats because the OS Does so. But in rust or other languages you would need to tune the OS. the JVM is its own OS. hope that gives you some insights.

in real world when you would see GC issues you could move the GC operation or avoid it or tune it. And GC is Implemented per OS Process. so if you eg: run 2 Processes they got indipendent GC rhythms.

lemanschik commented 1 year ago

@caoccao your touching here the topic "Realtime Computation" and for that you would need a special operating system and special hardware. In all other Modern Operating Systems you get something that you can call instant computation because scheduling is managed for you via a FIFO Algo First in First Out.

caoccao commented 1 year ago

@lemanschik I wonder what makes saying the 2 types of GC have their PROS and CONS so hard. There's a guy who told me they are the same and I'm wrong. I think I will quit this discussion.

lemanschik commented 1 year ago

@caoccao nothing has universal pro's and cons you need to know your payloads and workloads after that you could in theory say what would be a better fit until a external contributor delivers code that makes that assumption obsolete.

The only consistent way to handle GC and even none GC is to measure and then take actions. eg: adjusting some of the JVM start parameters, compiler options, or do code refactoring.