5
votes

I am working on a Java Card applet (for Java Card 2.2.1) which requires some temporary objects for processing APDU commands. I have questions about correct memory management. I have spent plenty of time on researching on the issues, but no where I have found any clarification or good sample codes on some java card APIs. I have 2 major questions:

  1. How can I create an array of transient objects (I mean custom objects in RAM not in EEPROM). I have read about makeTransientObjectArray but it returns only array of Object type. I know how to create for example, transient byte array using makeTransientByteArray, but my problem is about transient array of object instances. Or may be any way in java language to cast byte array to instances without serialization?

  2. I need this transient array of objects only during process of incoming APDU command and not need to keep the memory allocated for me. Where is the best place to allocate this transient memory (inside install, select, process, ... functions)?

Edited for more explanations:

  1. As I have already read from documentations, any object instance is stored in EEPROM. Assume that I know max number of objects I will need in my process algorithm (say 100). I generate 100 instances of MyClass inside install method. Each instance of MyClass contains 3 fields: field1 a short, field2 a byte, and field3 a short type. All these 100 instances will be filled by input of APDU command. If for each command, I fill objects on EEPROM, its not a good practice, because they are temporary data. Also EEPROM has a max wiriting cycles. An approach may be that for each instance, I allocate 5 bytes for each object using makeTransientByteArray and makeTransientShortArray. But as I have read from documentations, It allocates memory by clusters (of 32 bytes - not sure for size) which is not effective. So what I have to do in this scenario?

  2. I mean what to do for transient memory. If allocate transient memory inside install function, it will not be available for other applets. If the applet is the only one applet on the Card, it is a good practice to allocate all transient memory in install function. I want to know a general effective method for all conditions (single applet device or multi-applet device). Also I am not sure, if transient memory allocated inside install, will be available inside process function whenever the card is inserted in the card reader.

2

2 Answers

5
votes

Unfortunately what you are trying to do is not possible in the classic specification of Java Card. Object instances are always stored in EEPROM, as you already noticed yourself. So you have to work around the issue.

Java is a relatively high level language where objects are always stored in one particular piece of memory. Now they have changed that type of memory to persistent memory for Java Card. However, it would require a complete redesign of the language to allow objects to be constructed in one type of memory or another. Nowadays the JCF could of course consider using annotations for that - it would still be extremely tricky but possibly doable.

Likewise it isn't possible to have objects live only through one process method, not even the array types. To implement this you would have either have to have an addition heap or a real time garbage collector. It's hard enough to manage one heap and the stack growing towards each other, and a real time GC is not something that is present in the current classic implementations either. We're working with an extremely constrained environment here.

So basically you have to work around the restrictions of the platform.


One good strategy to use is to create a cache of objects that contain transient memory or reference existing memory such as memory within the APDU buffer. The objects would be created during installation or personalization. These objects then can be retrieved when necessary, used and returned to the cache. To give you an idea, take a look at Java's ByteBuffer.wrap() method that allows you to perform buffer operations on part of an existing array. Now consider a reuseable object of that type.

The other logical solution is not to use OO programming at all. Hey, OO is all nice and dandy, but we're talking about chips that have a RAM of 8 to 10 KiB here maximum. There will be restrictions. What can be done with objects can generally be done with just methods as well (actually, you can prove that this is the case as Java without objects is undoubtedly Turing-complete, but that's of little consolation if you're stuck with your design).


Notes on your text:

  • No, you cannot cast byte arrays to object instances. That would go all principles of Java and OO in general. Everything including data encapsulation would be broken if that would be possible. You can of course deserialize yourself and put the result in an object out of the cache (see the strategies above).
  • Memory should generally only be allocated during installation or personalization, or very possibly once after issuance using lazy instantiation.
  • You don't need 100 live objects. You only have a few objects that need to be "alive" at one particular time. Make use of that information!
  • Memory allocation is specific to the platform implementation. There are definitely platforms with smaller "cluster" sizes; platforms generally will try and align data in memory, so it depends on the design of the system / chip as well.
  • Memory that is created using CLEAR_ON_DESELECT may be available to other applets. If they are selected then this RAM is not needed anymore after all. A smart implementation would keep that memory on top of the heap (still tricky, but hey). As indicated, this becomes available after selection of the instance. The process method will only be called after the applet has been selected (even for handling the initial SELECT APDU itself).
4
votes

How can I create an array of transient objects (I mean custom objects in RAM not in EEPROM).

JavaCard specification provides a method makeTransientObjectArray(short, byte) to make an array of transient objects. This will allocate a memory on RAM and then you can store the reference of your objects in this memory.

Object[] aob = JCSystem.makeTransientObjectArray(lengthOfArray, CLEAR_ON_..event);
aob[0] = ((YourClass)new YourClass(param));
aob[1] = ((YourClass)new YourClass(param));
..

However, you cannot still completly acheive what you are trying to, because the objects instantiated in YourClass might be still be consuming memory from non transient memory (EEPROM) or transient (RAM) depending upon their allocation in the constructor of YourClass. It is only the reference of the objects of YourClass is what you are storing in a transient space (aob).

I need this transient array of objects only during process of incoming APDU command and not need to keep the memory allocated for me. Where is the best place to allocate this transient memory (inside install, select, process, ... functions)?

All resources should are best allocated in install() method.