Java Card中的内存分配

时间:2015-09-22 14:35:14

标签: java arrays memory javacard

我有一张Java Card智能卡,我想评估可用的EEPROM。

为此,我使用函数JCSystem.getAvailableMemory(JCSystem.MEMORY_TYPE_PERSISTENT)。 由于此函数的返回值是short,而没有分配任何数据,因此我得到值0x7FFF。为了解决这个问题,我以这种方式创建byte数组:new byte[(short) 0x7FFF]来推断可用的持久性内存。

如果我创建两个数组:

arr1 = new byte[(short) 0x7FFF];
arr2 = new byte[(short) 0x7FFF];

然后它根据0x1144休息JCSystem.getAvailableMemory(JCSystem.MEMORY_TYPE_PERSISTENT)字节的可用内存。所以,如果我求和,则意味着有32767 * 2 + 4420 = 69954字节可用。

但是当我改变数组的大小时:

arr1 = new byte[(short) 0x7FFF];
arr2 = new byte[(short) 0x6FFF];

然后它占用0x2244字节的可用内存。因此,如果我求和,则意味着有70210个字节可用。

另一个例子: 与

arr1 = new byte[(short) 0x7FFF];
arr2 = new byte[(short) 0x5FFF];

它占用0x3344字节的可用内存。所以,如果我总结它意味着有70466字节可用。

即使它可以忽略不计,为什么会出现这些差异?(70210与70466不同)。

以同样的方式,我想测试一下我可以在一个applet中分配多少AESKey。所以我尝试找到我之前描述的可用内存,但使用AESKey数组。

使用相同的卡,当我以这种方式创建AESKey阵列时:

arr = new AESKey[(short) 0x03E8];
for (short i = 0x0000; i < 0x03E8; i++) {
  arr[i] = (AESKey) KeyBuilder.buildKey(KeyBuilder.TYPE_AES,  KeyBuilder.LENGTH_AES_256, false);
}

所以我创建了一个256位AESKey的数组。我认为它需要32Ko,但方法JCSystem.getAvailableMemory(JCSystem.MEMORY_TYPE_PERSISTENT)表示有0x0022字节可用。为什么这个结果?

如果我用半键测试(例如500):

arr = new AESKey[(short) 0x01F4];
for (short i = 0x0000; i < 0x01F4; i++) {
   arr[i] = (AESKey) KeyBuilder.buildKey(KeyBuilder.TYPE_AES,  KeyBuilder.LENGTH_AES_256, false);
}

方法JCSystem.getAvailableMemory(JCSystem.MEMORY_TYPE_PERSISTENT)表示有0x55EE个(21998)字节可用:如果可用的EEPROM大约为70Ko,当我创建1000个密钥时,我肯定不会看到与该情况的关系就像我在开始时解释的那样......

有人可以详细描述如何在Java Card中分配内存来解释上面引用的结果吗?

2 个答案:

答案 0 :(得分:3)

这有几个原因:

  • 有对象分配开销;
  • 关于对齐数据可能会有开销;
  • 内存碎片可能会有开销;
  • 对于密钥,可能存在保护其安全的开销。

所有这些问题都会减少您可用的内存量。在这方面,您应该将getAvailableMemory视为可用内存的最大金额粗略指示

需要多少开销取决于Java Card运行时。

答案 1 :(得分:2)

嗯,简短回答:
Java Card不是聪明的存储阵列/它需要额外的数据。因此,如果用 x 字节填充字节数组以获得低于0x7FFF的阈值,则数组内部需要超过 x 字节来存储数据,因此您有所不同你注意到了。

如果您正在使用JCOP卡,则可以使用UtilX.getAvailableMemory()来解决问题。

要获得更多知识,请阅读: http://ruimtools.com/doc.php?doc=jc_best关于减少EEPROM消耗的点(但有些部分已过时)