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]

Reply via email to