chaokunyang commented on code in PR #170: URL: https://github.com/apache/fury-site/pull/170#discussion_r1730379255
##########
i18n/zh-CN/docusaurus-plugin-content-docs/current/guide/java_serialization_guide.md:
##########
@@ -0,0 +1,426 @@
+---
+title: Java 序列化指南
+sidebar_position: 0
+id: java_object_graph_guide
+---
+
+## Java 对象图序列化
+
+当只需要 Java 对象序列化时,其相比跨语言的图序列化拥有更好的性能。
+
+## 快速开始
+
+注意:Fury 对象创建的代价很高, 因此 **Fury 对象应该尽可能被复用**,而不是每次都重新创建。
+
+您应该创建一个全局的静态变量,或者单例变量和受限制的 Fury 变量。
+
+Fury 单线程用法:
+
+```java
+import java.util.List;
+import java.util.Arrays;
+
+import org.apache.fury.*;
+import org.apache.fury.config.*;
+
+public class Example {
+ public static void main(String[] args) {
+ SomeClass object = new SomeClass();
+ // Note that Fury instances should be reused between
+ // multiple serializations of different objects.
+ Fury fury = Fury.builder().withLanguage(Language.JAVA)
+ .requireClassRegistration(true)
+ .build();
+ // Registering types can reduce class name serialization overhead, but not
mandatory.
+ // If class registration enabled, all custom types must be registered.
+ fury.register(SomeClass.class);
+ byte[] bytes = fury.serialize(object);
+ System.out.println(fury.deserialize(bytes));
+ }
+}
+```
+
+Fury 多线程用法:
+
+```java
+import java.util.List;
+import java.util.Arrays;
+
+import org.apache.fury.*;
+import org.apache.fury.config.*;
+
+public class Example {
+ public static void main(String[] args) {
+ SomeClass object = new SomeClass();
+ // Note that Fury instances should be reused between
+ // multiple serializations of different objects.
+ ThreadSafeFury fury = new ThreadLocalFury(classLoader -> {
+ Fury f = Fury.builder().withLanguage(Language.JAVA)
+ .withClassLoader(classLoader).build();
+ f.register(SomeClass.class);
+ return f;
+ });
+ byte[] bytes = fury.serialize(object);
+ System.out.println(fury.deserialize(bytes));
+ }
+}
+```
+
+Fury 对象复用示例:
+
+```java
+import java.util.List;
+import java.util.Arrays;
+
+import org.apache.fury.*;
+import org.apache.fury.config.*;
+
+public class Example {
+ // reuse fury.
+ private static final ThreadSafeFury fury = new ThreadLocalFury(classLoader
-> {
+ Fury f = Fury.builder().withLanguage(Language.JAVA)
+ .withClassLoader(classLoader).build();
+ f.register(SomeClass.class);
+ return f;
+ });
+
+ public static void main(String[] args) {
+ SomeClass object = new SomeClass();
+ byte[] bytes = fury.serialize(object);
+ System.out.println(fury.deserialize(bytes));
+ }
+}
+```
+
+## FuryBuilder 参数选项
+
+| 参数选项名 | 描述
| 默认值
|
+|-------------------------------------|-----------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------|----------------------------------------------------------------|
+| `timeRefIgnored` | 启用 reference tracking 时,是否忽略在
`TimeSerializers` 中注册的所有时间类型及其子类的引用跟踪。如果忽略,则可以通过调用
`Fury#registerSerializer(Class, Serializer)`
来启用对每种时间类型的引用跟踪。例如,`fury.registerSerializer(Date.class, new
DateSerializer(fury, true))`。请注意,启用 ref tracking
功能应在任何包含时间字段的类型的序列化程序编码之前进行。否则,这些字段仍将跳过 reference tracking。 | `true`
|
+| `compressInt` | 启用或禁用 int 压缩,减小数据体积。
| `true`
|
+| `compressLong` | 启用或禁用 long 压缩,减小数据体积。
| `true`
|
+| `compressString` | 启用或禁用 String 压缩,减小数据体积。
| `true`
|
+| `classLoader` | 不应更新类加载器;Fury 会缓存类元数据。使用
`LoaderBinding` 或 `ThreadSafeFury` 进行类加载器更新。
| `Thread.currentThread().getContextClassLoader()`
|
+| `compatibleMode` | 类型的向前/向后兼容性配置。也与 `checkClassVersion`
配置相关。`schema_consistent`: 类模式必须在序列化对等节点和反序列化对等节点之间保持一致。`COMPATIBLE`:
序列化对等节点和反序列化对等节点之间的类模式可以不同。它们可以独立添加/删除字段。
|
`CompatibleMode.SCHEMA_CONSISTENT` |
+| `checkClassVersion` | 决定是否检查类模式的一致性。如果启用,Fury 将使用
`classVersionHash` 检查、写入和检查一致性。当启用 `CompatibleMode#COMPATIBLE`
时,它将自动禁用。除非能确保类不会演化,否则不建议禁用。
|
`false` |
+| `checkJdkClassSerializable` | 启用或禁用 `java.*` 下类的 `Serializable`
接口检查。如果 `java.*` 下的类不是 `Serializable`,Fury 将抛出 `UnsupportedOperationException`。
| `true` |
+| `registerGuavaTypes` | 是否预先注册 Guava 类型,如
`RegularImmutableMap`/`RegularImmutableList`。这些类型不是公共 API,但似乎非常稳定。
| `true`
|
+| `requireClassRegistration` | 禁用可能会允许未知类被反序列化,从而带来潜在的安全风险。
| `true` |
+| `suppressClassRegistrationWarnings` |
是否抑制类注册警告。这些警告可用于安全审计,但可能会令人反感,默认情况下将启用此抑制功能。
| `true` |
+| `metaShareEnabled` | 是否否开启原元数据共享。
| `false`
|
+| `scopedMetaShareEnabled` |
范围元数据共享侧重于单一序列化流程。在此过程中创建或识别的元数据为该过程独有,不会与其他序列化过程共享。
| `false`
|
+| `metaCompressor` | 元数据压缩器。请注意,传递的元压缩器应是线程安全的。默认情况下,将使用基于
`Deflater` 的压缩器 `DeflaterMetaCompressor`。用户可以使用其他压缩器,如 `zstd` 以获得更好的压缩率。
| `DeflaterMetaCompressor` |
+| `deserializeNonexistentClass` | 启用或禁用反序列化/跳转不存在类的数据。
| `true`, 如果设置了 `CompatibleMode.Compatible`,将会变为 `false`。 |
+| `codeGenEnabled` | 禁用后,初始序列化速度会加快,但后续序列化速度会减慢。
| `true` |
+| `asyncCompilationEnabled` | 如果启用,序列化会首先使用解释器模式,并在类的异步序列化 JIT
完成后切换到 JIT 序列化。
| `false`
|
+| `scalaOptimizationEnabled` | 启用或禁用特定于 Scala 的序列化优化。
| `false`
|
+| `copyRef` | 禁用后,复制性能会更好。但 Fury
深度复制将忽略循环引用和共享引用。对象图中的相同引用将在一次 `Fury#copy` 中复制到不同的对象中。
| `true`
|
+
+## 高级用法
+
+### Fury 创建
+
+单线程 Fury 创建:
+
+```java
+Fury fury=Fury.builder()
+ .withLanguage(Language.JAVA)
+ // enable reference tracking for shared/circular reference.
+ // Disable it will have better performance if no duplicate reference.
+ .withRefTracking(false)
+ .withCompatibleMode(CompatibleMode.SCHEMA_CONSISTENT)
+ // enable type forward/backward compatibility
+ // disable it for small size and better performance.
+ // .withCompatibleMode(CompatibleMode.COMPATIBLE)
+ // enable async multi-threaded compilation.
+ .withAsyncCompilation(true)
+ .build();
+ byte[]bytes=fury.serialize(object);
+ System.out.println(fury.deserialize(bytes));
+```
+
+多线程 Fury 创建:
+
+```java
+ThreadSafeFury fury=Fury.builder()
+ .withLanguage(Language.JAVA)
+ // enable reference tracking for shared/circular reference.
+ // Disable it will have better performance if no duplicate reference.
+ .withRefTracking(false)
+ // compress int for smaller size
+ // .withIntCompressed(true)
+ // compress long for smaller size
+ // .withLongCompressed(true)
+ .withCompatibleMode(CompatibleMode.SCHEMA_CONSISTENT)
+ // enable type forward/backward compatibility
+ // disable it for small size and better performance.
+ // .withCompatibleMode(CompatibleMode.COMPATIBLE)
+ // enable async multi-threaded compilation.
+ .withAsyncCompilation(true)
+ .buildThreadSafeFury();
+ byte[]bytes=fury.serialize(object);
+ System.out.println(fury.deserialize(bytes));
+```
+
+### 受限的 Fury 对象创建:
+
+`FuryBuilder#withIntCompressed`/`FuryBuilder#withLongCompressed` 可用于压缩
`int/long`,使其体积更小。通常压缩 int 类型就足够了。
+
+如果序列化不重要,这两种压缩属性默认启用。序列化时,不会压缩任何东西,此时就应该禁用压缩。如果数据都是数字,压缩可能会带来 80% 的性能损耗。
+
+对于 int 压缩,Fury 使用 1~5
字节进行编码。每个字节的第一位表示是否有下一个字节位,如果下一个字节位被设置,则将读取下一个字节,直到下一个字节位未被设置时停止。
+
+对于 long 压缩,Fury 支持两种编码方式:
+
+- Fury SLI(Small long as int)编码(**默认使用**):
+ - 如果 long 在 [-1073741824, 1073741823] 范围内,则编码为 4 字节 int:`| little-endian:
((int) value) << 1 |`
+ - 否则写成 9 字节: `| 0b1 | little-endian 8 bit long |`
+- Fury PVL(渐进可变长)编码:
+ - 每个字节的第一位表示是否有下一个字节。如果第一位被设置,则将读取下一个字节。
+ 直到下一字节的第一位未设置。
+ - 负数将通过 `(v << 1) ^ (v >> 63)` 转换为正数,以减少小负数的代价。
+
+如果一个数字是 “长 ”类型,大多不能用更小的字节表示,压缩效果就不够好。
+与性能成本相比,这是不值得的。如果您发现长压缩并没有带来多少好处,也许您应该尝试禁用长压缩,以节省空间。
Review Comment:
```suggestion
与占用的性能开销相比,这是不值得的。如果您发现`Long`类型压缩并没有带来多少好处,也许您应该尝试关闭`Long`类型压缩,以提升性能。
```
--
This is an automated message from the Apache Git Service.
To respond to the message, please log on to GitHub and use the
URL above to go to the specific comment.
To unsubscribe, e-mail: [email protected]
For queries about this service, please contact Infrastructure at:
[email protected]
---------------------------------------------------------------------
To unsubscribe, e-mail: [email protected]
For additional commands, e-mail: [email protected]
