2

I know that Java Card VM's doesn't have have a garbage collector, but what happens with a for loop:

for(short x=0;x<10;x++)
{}

Does the x variable get utilized after the for loop, or it turns into garbage?

Just in case I have a transient byte array called index from size of 2 (instead of i in for loop) and I use the array in for loops:

for(index[0]=0;index[0]<10;index[0]++)
{}

But it is a little slower than the first version. If I use a normal variable for the index in a for loop then it gets really slow.

So, what happens with the x variable in the first for loop? Is it safe to use for loops like that, or not?

Maarten Bodewes
  • 90,524
  • 13
  • 150
  • 263
TajnosAgentos
  • 167
  • 1
  • 1
  • 10

2 Answers2

7

The x variable does not really exist in byte code. There are operations on a location in the Java stack that represents x (be it Java byte code or the code after conversion by the Java Card converter). Now the Java stack is a virtual stack. This stack is implemented on a CPU that has registers and a non-virtual stack. In general, if there are enough registers available, then the variable x is simply put in a register until it is out of scope. The register may of course be reused. The CPU stack itself is a LIFO (last in first out) queue in transient memory (RAM). The stack continuously grows and shrinks during the execution of the byte code that makes up your Applet. Like registers, the stack memory is reused over and over again. All the local variables (those defined inside code blocks as well as method arguments) are treated this way.

If you put your variable in a transient array then you are putting the variable on a RAM based heap. The Java Card RAM heap will never go out of scope. That means that if you update the value that the change needs to be written to transient memory. That is of course slower than a localized update of a CPU register, as you found by experimentation. Usually the memory in the transient memory is never freed. That said, you can of course reuse the memory for other purposes, as long as you have a reference to the array. Note that the references themselves (the index in index[0]) may be either in persistent memory (EEPROM or flash) or transient memory.

It's unclear what you mean with "normal variable". If this is something that has been created with new or if it is a field in an object instance then it persists in the heap in persistent memory (EEPROM or flash). EEPROM and flash have limited amount of write cycles and writing to EEPROM or flash is much much slower than writing to RAM.


Java Card contains two kinds of transient memory: CLEAR_ON_RESET and CLEAR_ON_DESELECT. The difference between the two is that the CLEAR_ON_RESET allows memory to be shared between Applet instances while the CLEAR_ON_DESELECT allows memory to be reused by different Applets.

Java Card classic doesn't contain a garbage collector that runs during Applet execution, you can usually only request garbage collection during startup using JCSystem.requestObjectDeletion() which will clean up the memory that is not referenced anymore, both on the heap in transient memory as well as in persistent memory. Cleaning up the memory means scanning all the memory, marking all the unreferenced blocks and then compacting the memory. This is similar to defragmenting a hard disk; it can take a uncomfortably long time.

ROM is filled during the manufacturing phase. It may contain the operating system, the Java Card API implementation, byte code (including constants) of pre-loaded applets etc. It only be read in the field, so it isn't of any consequence to the question asked.

Maarten Bodewes
  • 90,524
  • 13
  • 150
  • 263
2

Let us have a short introduction about the Memory. In brief, there is 3 types of memories in the Smart cards as below:

  • ROM (And sometimes FLASH)
  • EEPROM
  • RAM

ROM:

The card's OS and Java Card APIs and some factory proprietary packages stored here. The contents of this memory is fixed and you can't modify it. Writing in this memory happens only once in the chip production and the process is named Masking.

EEPROM:

This is modifiable memory that your applets load into and it is consist of 4 sections named as below:

  1. Text : also known as code segment contains the machine instructions of the program. The code can be thought of like the text of a novel: It tells the story of what the program does
  2. Data : contains the static data of the program, i.e. the variables that exist throughout program execution. Global variables in a C or C++ program are static, as are variables declared as static in C, C++, or Java.
  3. Heap : is a pool of memory used for dynamically allocated memory, such as with malloc() in C or new in C++ and Java.
  4. Stack : contains the system stack, which is used as temporary storage.

A power-less (Card tearing for example) doesn't have any effect on the contents of this memory.

RAM:

This is a modifiable type of memory also. There is three main difference between RAM and EEPROM:

  1. RAM is really faster than EEPROM. (1000 times faster)
  2. Contents of RAM will destroyed in the power-loss.
  3. The number of writing in EEPROM is limited (Typically 100.000 times.) while RAM has a really higher number.

And What now?

When you write for(short x=0; x<10; x++), you define x as a local variable. Local variables stores in Stack. The stack pointer will reset on the power loss and the used stack part will reclaim. So the main problem of the absence of Garbage Collector is about Heap.

i.e when you define a local variable using new keyword, you specify that part of Heap to a local variable for ever. When the Runtime Environment finished that method, the object will destroy and become unavailable, while that section of Heap doesn't reclaimed. So you will lose that part of Heap. The case that you used for yourfor loop, seems OK and doesn't make any problem because you didn't use new keyword.

Note that in newer versions of Java Card (2.2.2 and higher) there is a manual Garbage Collector (look JCSystem.requestObjectDeletion documentation). But consider that it is really slow and even dangerous in some situations(Look Java Card power less during garbage collection question).

Community
  • 1
  • 1
Ebrahim Ghasemi
  • 5,850
  • 10
  • 52
  • 113
  • **I'm NOT SURE about some parts of my answer. please wait for our other friends's comments :)** – Ebrahim Ghasemi Jun 04 '15 at 05:27
  • 3
    _When you write `for(short x=0; x<10; x++)`, you define x as a local variable. Local variables stores in Stack_ - yes, they are, but the Stack itself is not in EEPROM (which is what you say in your post). It would be slow and the card would be damaged soon. `short x` from the line mentioned above is stored in RAM. – vojta Jun 04 '15 at 05:49
  • 2
    You've put the stack in EEPROM. It of course isn't - it's in RAM. Note that although the Java VM is a stack machine (i.e. it doesn't define registers) it may be that the stack may be *implemented* in such a way that the variables on the Java stack are actually put into the CPU registers (which are really fast). Smart card CPU's don't have a lot of registers so using too many variables in a method may slow your Applet down. – Maarten Bodewes Jun 05 '15 at 23:30
  • @vojta Thank you. I'll edit or remove my answer. Am I wrong about the sections of EEPROM also? Heap is in RAM also? – Ebrahim Ghasemi Jun 06 '15 at 05:11