哪些对象在 Java Card 中持久存在,何时存在?
Which objects are persistent in Java Card, and when?
这个问题是双重的,但希望不要过长地回答这个问题,尽管它本身很长。不过,请随意只回答其中的一部分,很抱歉让它如此详尽!
- 哪些对象被持久化了?哪些对象是瞬态的?
- 对象何时持久化?
对于第一部分,问题适用于:
- 存储在
Applet
中的对象
- 可传递存储在
Applet
中的对象
- 仅存储在堆栈变量中的对象(未从任何
Applet
引用,甚至可传递)
- 存储在使用
makeTransientObjectArray
构建的数组中的对象
- 传递存储在数组中的对象
makeTransientObjectArray
(例如,存储在 makeTransientObjectArray
中存储的对象的成员变量中)
第二部分,根据第一个问题的答案而定。例如:
- 我假设直接存储在瞬态对象数组中的对象不会持久化。在这种情况下,假设堆栈上的对象是持久化的,存储在那里的对象什么时候变成非持久化的?它是否在
new Object
处持久化并且在放入瞬态对象数组时不持久化?
- 如果一个对象同时具有来自瞬态对象数组和小程序的引用,并且小程序引用被删除,该对象是否已取消持久化?
提前致谢!
我查看了 JCRE 规范 v2.2.2(我正在使用的版本),但其中有些地方不清楚(因此这个问题很详尽,因为我觉得这更适合Q/A-style 论坛):
- 第 2-2 页提到 JCRE 在将对象临时存储在
Applet
中时使对象持久化。但是,Glossary-7 声明对象默认是持久的。差异可能看起来不可观察,但会影响是否需要垃圾收集,因为无论如何都需要卡电源循环。
- 第 5-1 页指出,瞬态对象的字段绝不能存储在持久内存中。但它没有说明这是否也适用于瞬态对象数组中的可传递对象,例如。存储在瞬态对象数组中对象字段中的对象。
- 第 5-1 页,同样的语句,可能与第 2-2 页冲突,当一个对象引用它存储在瞬态对象数组和
Applet
. 中时
这三道题分别相当于:
- 第 1 部分要点 3 和 5(以及第 2 部分要点 1,具体取决于答案)
- 第 1 部分要点 5
- 第 2 部分要点 2
有一个非常好的文档,可以从 oracle.com 免费下载,标题为 "Java Card 3 Platform Runtime Environment Specification"
Q: Which objects are persisted? Which objects are transient?
所有对象实例字段在使用 new
创建时都是持久的。 JRE 创建的对象可能不是:您必须检查 Java Card 或 OS 文档才能找到答案。请注意,其他对象的字段是 references。这些引用本身可能指向临时内存中的数组或其他包含易失状态的对象。
如果数组已被创建或定义为瞬态(通常通过调用 makeTransientXxxArray()
),则数组是瞬态的。使用 new
.
创建时它们是持久的
Q: When is an object persisted?
创建时或任何更新期间。通常,持久值只是简单地放在持久内存中:闪存或 EEPROM。对闪存或 EEPROM 的任何写入都会直接保留。请注意,Java 卡交易机制仍然可以 回滚 对持久内存的更改。
这与 Java SE 非常不同,后者的对象实例存储在 RAM 中,因此需要在创建和每次更新后持久化(如果它们被持久化完全没有)。
Q: For the first part, the question applies to: ...
不,现在你把它变得不必要的复杂了。对象的字段总是持久化的。他们如何被引用并不重要。
引用本身可能不是持久的,即使对象是。例如,它可能位于瞬态对象数组或局部变量中。如果所有引用都丢失,则无法再访问该对象,并且它有资格进行垃圾回收。但在收集之前,它仍将保留在持久内存中。
I assume objects that are directly stored in a transient object array are not persisted. In this case and assuming objects on the stack are persisted, when does the object stored there become not-persisted? Is it persisted at the new Object and un-persisted when being put into the transient object array?
考虑之前的答案。真的没有 "transient object array" 这样的东西。存在的是一个由 对其他对象的引用 组成的数组。这些引用可能是暂时的或持久的。引用的对象可能是瞬态(数组)或包含对瞬态值的引用。
对象本身通常 不会从持久性转换为瞬态,反之亦然。他们不关心如何引用它们。他们只关心他们的引用计数是否不为零,因为那样他们就会丢失并有资格进行垃圾收集。如果它们只是被瞬态对象数组或局部变量中的 volatile 引用引用,这当然更有可能。
堆栈本身总是在临时内存中。它包括所有局部变量(包括参数和 return 值)。但同样:它不包含任何对象:它可能只包含 对对象 在堆上 的瞬态引用 。如果这些引用丢失,则该对象可能会被垃圾回收。
备注:
- 我这里说的是经典 Java卡在这里;
- Java Card 还包含特殊对象,例如 APDU 缓冲区,它有自己的生命周期;
- 通常你会一直使用持久引用指向对象,因为你不想对Java卡上的运行进行垃圾回收,除非在特殊情况下。 - 瞬态数组在重置后被引用时为零。 OS(应该)确保它们始终可用。
- 即使其他小程序可用,
CLEAR_ON_RESET
数组也会保留其内容。但是 这意味着其他小程序无法重用该临时内存,而小程序的 RAM 不足是出了名的 。因此,您应该默认使用 CLEAR_ON_DESELECT
瞬态数组,除非 上下文切换 . 需要 CLEAR_ON_RESET
功能
这个问题是双重的,但希望不要过长地回答这个问题,尽管它本身很长。不过,请随意只回答其中的一部分,很抱歉让它如此详尽!
- 哪些对象被持久化了?哪些对象是瞬态的?
- 对象何时持久化?
对于第一部分,问题适用于:
- 存储在
Applet
中的对象
- 可传递存储在
Applet
中的对象
- 仅存储在堆栈变量中的对象(未从任何
Applet
引用,甚至可传递) - 存储在使用
makeTransientObjectArray
构建的数组中的对象
- 传递存储在数组中的对象
makeTransientObjectArray
(例如,存储在makeTransientObjectArray
中存储的对象的成员变量中)
第二部分,根据第一个问题的答案而定。例如:
- 我假设直接存储在瞬态对象数组中的对象不会持久化。在这种情况下,假设堆栈上的对象是持久化的,存储在那里的对象什么时候变成非持久化的?它是否在
new Object
处持久化并且在放入瞬态对象数组时不持久化? - 如果一个对象同时具有来自瞬态对象数组和小程序的引用,并且小程序引用被删除,该对象是否已取消持久化?
提前致谢!
我查看了 JCRE 规范 v2.2.2(我正在使用的版本),但其中有些地方不清楚(因此这个问题很详尽,因为我觉得这更适合Q/A-style 论坛):
- 第 2-2 页提到 JCRE 在将对象临时存储在
Applet
中时使对象持久化。但是,Glossary-7 声明对象默认是持久的。差异可能看起来不可观察,但会影响是否需要垃圾收集,因为无论如何都需要卡电源循环。 - 第 5-1 页指出,瞬态对象的字段绝不能存储在持久内存中。但它没有说明这是否也适用于瞬态对象数组中的可传递对象,例如。存储在瞬态对象数组中对象字段中的对象。
- 第 5-1 页,同样的语句,可能与第 2-2 页冲突,当一个对象引用它存储在瞬态对象数组和
Applet
. 中时
这三道题分别相当于:
- 第 1 部分要点 3 和 5(以及第 2 部分要点 1,具体取决于答案)
- 第 1 部分要点 5
- 第 2 部分要点 2
有一个非常好的文档,可以从 oracle.com 免费下载,标题为 "Java Card 3 Platform Runtime Environment Specification"
Q: Which objects are persisted? Which objects are transient?
所有对象实例字段在使用 new
创建时都是持久的。 JRE 创建的对象可能不是:您必须检查 Java Card 或 OS 文档才能找到答案。请注意,其他对象的字段是 references。这些引用本身可能指向临时内存中的数组或其他包含易失状态的对象。
如果数组已被创建或定义为瞬态(通常通过调用 makeTransientXxxArray()
),则数组是瞬态的。使用 new
.
Q: When is an object persisted?
创建时或任何更新期间。通常,持久值只是简单地放在持久内存中:闪存或 EEPROM。对闪存或 EEPROM 的任何写入都会直接保留。请注意,Java 卡交易机制仍然可以 回滚 对持久内存的更改。
这与 Java SE 非常不同,后者的对象实例存储在 RAM 中,因此需要在创建和每次更新后持久化(如果它们被持久化完全没有)。
Q: For the first part, the question applies to: ...
不,现在你把它变得不必要的复杂了。对象的字段总是持久化的。他们如何被引用并不重要。
引用本身可能不是持久的,即使对象是。例如,它可能位于瞬态对象数组或局部变量中。如果所有引用都丢失,则无法再访问该对象,并且它有资格进行垃圾回收。但在收集之前,它仍将保留在持久内存中。
I assume objects that are directly stored in a transient object array are not persisted. In this case and assuming objects on the stack are persisted, when does the object stored there become not-persisted? Is it persisted at the new Object and un-persisted when being put into the transient object array?
考虑之前的答案。真的没有 "transient object array" 这样的东西。存在的是一个由 对其他对象的引用 组成的数组。这些引用可能是暂时的或持久的。引用的对象可能是瞬态(数组)或包含对瞬态值的引用。
对象本身通常 不会从持久性转换为瞬态,反之亦然。他们不关心如何引用它们。他们只关心他们的引用计数是否不为零,因为那样他们就会丢失并有资格进行垃圾收集。如果它们只是被瞬态对象数组或局部变量中的 volatile 引用引用,这当然更有可能。
堆栈本身总是在临时内存中。它包括所有局部变量(包括参数和 return 值)。但同样:它不包含任何对象:它可能只包含 对对象 在堆上 的瞬态引用 。如果这些引用丢失,则该对象可能会被垃圾回收。
备注:
- 我这里说的是经典 Java卡在这里;
- Java Card 还包含特殊对象,例如 APDU 缓冲区,它有自己的生命周期;
- 通常你会一直使用持久引用指向对象,因为你不想对Java卡上的运行进行垃圾回收,除非在特殊情况下。 - 瞬态数组在重置后被引用时为零。 OS(应该)确保它们始终可用。
- 即使其他小程序可用,
CLEAR_ON_RESET
数组也会保留其内容。但是 这意味着其他小程序无法重用该临时内存,而小程序的 RAM 不足是出了名的 。因此,您应该默认使用CLEAR_ON_DESELECT
瞬态数组,除非 上下文切换 . 需要
CLEAR_ON_RESET
功能