我有一张 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];
然后它根据 JCSystem.getAvailableMemory(JCSystem.MEMORY_TYPE_PERSISTENT)
占用 0x1144
字节的可用内存。因此,如果我求和,则意味着有 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 不同)。
同理,我想测试一下我可以在一个小程序中分配多少个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);
}
所以我创建了一个包含 1000 个 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 个 key ,就像我在开始时解释的那样...
谁能详细描述一下 Java Card 中内存是如何分配的,以解释上面引用的结果?
最佳答案
这有几个原因:
- 存在对象分配开销;
- 对齐数据可能会产生开销;
- 内存碎片可能会产生开销;
- 对于 key ,可能会有开销来保证它们的安全。
所有这些问题都会减少您可用的内存量。在这方面,您应该将 getAvailableMemory
视为可用内存的最大数量的粗略指示。
需要多少开销取决于 Java Card 运行时。
关于java - Java Card 中的内存分配,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/32719758/