This is an automated email from the ASF dual-hosted git repository.
chaokunyang pushed a commit to branch main
in repository https://gitbox.apache.org/repos/asf/fory-site.git
The following commit(s) were added to refs/heads/main by this push:
new 1801651853 π synced local 'docs/guide/' with remote 'docs/guide/'
1801651853 is described below
commit 1801651853058622e63333c6ac4a631812960c6b
Author: chaokunyang <[email protected]>
AuthorDate: Fri Mar 27 10:52:22 2026 +0000
π synced local 'docs/guide/' with remote 'docs/guide/'
---
docs/guide/java/index.md | 23 +++++++++-
docs/guide/java/virtual-threads.md | 87 ++++++++++++++++++++++++++++++++++++++
2 files changed, 108 insertions(+), 2 deletions(-)
diff --git a/docs/guide/java/index.md b/docs/guide/java/index.md
index 0d46a52c98..dc8856d082 100644
--- a/docs/guide/java/index.md
+++ b/docs/guide/java/index.md
@@ -151,9 +151,25 @@ byte[] bytes = fory.serialize(object);
System.out.println(fory.deserialize(bytes));
```
+### Virtual Threads
+
+For JDK 21+ virtual-thread workloads, use `buildVirtualThreadSafeFory(...)`:
+
+```java
+ThreadSafeFory fory = Fory.builder()
+ .withLanguage(Language.JAVA)
+ .withRefTracking(false)
+ .withCompatibleMode(CompatibleMode.SCHEMA_CONSISTENT)
+ .withAsyncCompilation(true)
+ .buildVirtualThreadSafeFory();
+```
+
+See more details in [Virtual Threads](virtual-threads.md).
+
### ThreadSafeForyPool
-For virtual threads or environments where thread-local storage is not
appropriate, use `buildThreadSafeForyPool`:
+For environments where thread-local storage is not appropriate and you need
the existing
+time-expiring pooled runtime, use `buildThreadSafeForyPool`:
```java
ThreadSafeFory fory = Fory.builder()
@@ -164,7 +180,9 @@ ThreadSafeFory fory = Fory.builder()
.buildThreadSafeForyPool(minPoolSize, maxPoolSize);
```
-Note that calling `buildThreadSafeFory()` on `ForyBuilder` will create an
instance of `ThreadLocalFory`. This may not be appropriate in environments
where virtual threads are used, as each thread will create its own Fory
instance, a relatively expensive operation. An alternative for virtual threads
is to use `buildThreadSafeForyPool`.
+Note that calling `buildThreadSafeFory()` on `ForyBuilder` creates a
`ThreadLocalFory`. This is
+not a good default for virtual-thread workloads because each virtual thread
can create its own
+`Fory` instance. For virtual threads, prefer `buildVirtualThreadSafeFory(...)`.
### Builder Methods
@@ -190,6 +208,7 @@ ThreadSafeFory fory = Fory.builder()
- [Configuration](configuration.md) - Learn about ForyBuilder options
- [Basic Serialization](basic-serialization.md) - Detailed serialization
patterns
+- [Virtual Threads](virtual-threads.md) - Virtual-thread usage and pool sizing
guidance
- [Type Registration](type-registration.md) - Class registration and security
- [Custom Serializers](custom-serializers.md) - Implement custom serializers
- [Cross-Language Serialization](cross-language.md) - Serialize data for other
languages
diff --git a/docs/guide/java/virtual-threads.md
b/docs/guide/java/virtual-threads.md
new file mode 100644
index 0000000000..b42b2a2f58
--- /dev/null
+++ b/docs/guide/java/virtual-threads.md
@@ -0,0 +1,87 @@
+---
+title: Virtual Threads
+sidebar_position: 11
+id: java_virtual_threads
+license: |
+ Licensed to the Apache Software Foundation (ASF) under one or more
+ contributor license agreements. See the NOTICE file distributed with
+ this work for additional information regarding copyright ownership.
+ The ASF licenses this file to You under the Apache License, Version 2.0
+ (the "License"); you may not use this file except in compliance with
+ the License. You may obtain a copy of the License at
+
+ http://www.apache.org/licenses/LICENSE-2.0
+
+ Unless required by applicable law or agreed to in writing, software
+ distributed under the License is distributed on an "AS IS" BASIS,
+ WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ See the License for the specific language governing permissions and
+ limitations under the License.
+---
+
+Apache Foryβ’ Java provides `buildVirtualThreadSafeFory(...)` for JDK 21+
virtual-thread workloads.
+
+## When `buildVirtualThreadSafeFory` Is Enough
+
+If your code uses the byte-array or `MemoryBuffer` APIs directly,
`buildVirtualThreadSafeFory(...)`
+is usually enough:
+
+```java
+ThreadSafeFory fory = Fory.builder()
+ .requireClassRegistration(false)
+ .buildVirtualThreadSafeFory();
+```
+
+This is the preferred choice when serialization work is CPU-bound and each
virtual thread only
+needs a `Fory` instance while it is actively encoding or decoding data.
+
+Examples:
+
+- `serialize(Object)`
+- `serialize(MemoryBuffer, Object)`
+- `deserialize(byte[])`
+- `deserialize(MemoryBuffer)`
+- `copy(Object)`
+
+## When Blocking I/O Changes The Tradeoff
+
+If your code uses Java I/O or NIO based APIs such as:
+
+- `serialize(OutputStream, Object)`
+- `deserialize(ForyInputStream)`
+- `deserialize(ForyReadableChannel)`
+
+then virtual threads can yield while blocked on I/O.
+
+That matters because the borrowed `Fory` instance stays occupied for the whole
operation, including
+the time spent waiting on the stream or channel. In that case, many virtual
threads can require
+many `Fory` instances at the same time.
+
+Each `Fory` instance uses about `30+ KB` of memory. As a rough estimate, `100
MB` of memory can
+hold `3000+` `Fory` instances.
+
+Before using `buildVirtualThreadSafeFory(...)` for stream or channel heavy
workloads, evaluate:
+
+- whether you may have too many concurrent virtual threads blocked on I/O
+- whether you have enough memory for the needed number of `Fory` instances
+- whether a lower pool cap will cause extra waiting
+
+## Pool Exhaustion Behavior
+
+`buildVirtualThreadSafeFory(int maxPoolSize)` limits how many idle `Fory`
instances are retained
+for reuse after operations complete.
+
+If stream or channel operations cause many virtual threads to block while
holding pooled `Fory`
+instances, and there are not enough available instances for the ready virtual
threads, those ready
+virtual threads may still need to yield again while waiting for another `Fory`
instance to become
+free.
+
+In other words:
+
+- blocked I/O can keep `Fory` instances occupied for longer
+- ready virtual threads may wait for a free `Fory` even after their stream
becomes ready
+- too small a retained pool can add extra scheduling delay under heavy
blocking I/O
+
+If that is not acceptable, prefer the first approach: use
`buildVirtualThreadSafeFory(...)` only
+for non-stream, non-channel serialization paths, or provision enough memory
for the number of
+`Fory` instances your workload can keep active.
---------------------------------------------------------------------
To unsubscribe, e-mail: [email protected]
For additional commands, e-mail: [email protected]