Which objects are persistent in Java Card, and when?

Ekleog :

This question is twofold, but hopefully shouldn't be unreasonably long to answer, despite its own length. Feel free to answer only part of it, though, and sorry for making it so exhaustive!

  • Which objects are persisted? Which objects are transient?
  • When is an object persisted?

For the first part, the question applies to:

  • Objects that are stored in an Applet
  • Objects that are transitively stored in an Applet
  • Objects that are only stored in stack variables (not referenced, even transitively, from any Applet)
  • Objects that are stored in an array built with makeTransientObjectArray
  • Objects that are transitively stored in an array build with makeTransientObjectArray (eg. stored in a member variable of an object stored in a makeTransientObjectArray)

For the second part, it applies depending on the answer of the first question. For instance:

  • 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?
  • If an object has references from both a transient object array and an applet, and the applet reference is erased, is the object un-persisted?

Thank you in advance!


I have looked into the JCRE specification v2.2.2 (the version I'm using), but there are points that are unclear in it (hence the exhaustiveness of this question, as I feel this is more appropriate for a Q/A-style forum):

  • Page 2-2 mentions that the JCRE makes an object persistent when it's transitively stored in an Applet. However, Glossary-7 states that objects are persistent by default. The difference may seem non-observable, but affects the need to garbage-collect or not when a card power cycle is needed anyway.
  • Page 5-1 states that the fields of a transient object must never be stored in persistent memory. But it doesn't state whether this is also true for objects transitively in a transient object array, eg. objects stored in fields of objects in a transient object array.
  • Page 5-1, same statements, may conflict with page 2-2, when an object has a reference to it stored both in a transient object array and in an Applet.

These three questions are respectively equivalent to:

  • part 1 bullet points 3 and 5 (and, depending on the answer, part 2 bullet point 1)
  • part 1 bullet point 5
  • part 2 bullet point 2
Maarten Bodewes :

Q: Which objects are persisted? Which objects are transient?

All object instance fields are persistent when they are created using new. Objects created by the JRE may not be: you'd have to check the Java Card or OS documentation to find out. Note that fields to other objects are references. Those references themselves may point to arrays in transient memory or to other objects that contain volatile state.

Arrays are transient if they have been created or defined as being transient (usually by calling makeTransientXxxArray()). They are persistent when they are created using new.

Q: When is an object persisted?

Upon creation or during any update. Generally the persistent values are simply put in persistent memory: flash or EEPROM. Any write to flash or EEPROM is persisted directly. Note that the Java Card transaction mechanism can still roll back changes to persistent memory.

This is very different from Java SE where objects instances are stored in RAM, and therefore need to be persisted after creation and each update (if they are persisted at all).

Q: For the first part, the question applies to: ...

No, now you're making it unnecessarily complex. The fields of an object are always persisted. How they are referred to doesn't matter.

The reference itself may not be persistent, even if the object is. It may be in a transient object array or local variable for instance. If all references are lost then the object cannot be accessed anymore and it becomes eligible for garbage collection. But before it is collected it will still remain in persistent memory.

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?

Consider the previous answer. There is really no such thing as a "transient object array". What exists is an array that consists of references to other objects. These references may be transient or persistent. The objects referenced may be transient (arrays) or contain references to transient values.

Objects themselves generally do not convert from persistent to transient or vice versa. They don't care how they are referenced. They only care if their reference count doesn't become zero, because then they are lost and eligible for garbage collection. This is of course more likely if they are just referenced by a volatile reference in a transient object array or in a local variable.

The stack itself is always in transient memory. It includes all local variables (including parameters and return values). But again: it doesn't contain any objects: it may just contain transient references to objects on the heap. If those references are lost then the object may be garbage collected.


Notes:

  • I'm just talking about classic Java Card here;
  • Java Card also contains special objects such as the APDU buffer which has it's own life cycle;
  • Generally you will always use persistent references to point to objects, as you don't want to garbage collection to run on Java Card unless at exceptional circumstances. - Transient arrays are zero'd when they are referenced after a reset. The OS (should) make sure that they are always available.
  • The CLEAR_ON_RESET arrays keep their contents even if other applets are available. But this means that the other applets cannot reuse that transient memory, and applets are notoriously RAM starved. Therefore you should default to CLEAR_ON_DESELECT transient arrays unless CLEAR_ON_RESET functionality is required for context switches.

Guess you like

Origin http://43.154.161.224:23101/article/api/json?id=80177&siteId=1