[英]What is the efficient way in writing a java card applet?
关于缺少垃圾收集器,我感到困惑的是,定义字段和变量的最佳方法是什么? 我们知道,在Java Card技术中,使用new
关键字分配的那些对象在超出范围时将变得不可访问,但是它们所占用的存储空间将永远不会被回收。
现在,假设我要在接收每个APDU命令时发送“ Hello”。
这些实现之间的区别是什么(内存和CPU消耗)? 哪一个最好,为什么?
1-
public class SimpleApp extends Applet {
byte[] hello = { (byte) 'H', (byte) 'e', (byte) 'l', (byte) 'l', (byte) 'o' };;
private SimpleApp() {
}
public static void install(byte bArray[], short bOffset, byte bLength)
throws ISOException {
new SimpleApp().register();
}
public void process(APDU arg0) throws ISOException {
byte[] buffer = arg0.getBuffer();
Util.arrayCopyNonAtomic(hello, (short) 0, buffer, (short) 0, (short) 5);
arg0.setOutgoingAndSend((short) 0, (short) 5);
}
}
2-
public class SimpleApp extends Applet {
static byte[] hello = { (byte) 'H', (byte) 'e', (byte) 'l', (byte) 'l', (byte) 'o' };;
private SimpleApp() {
}
public static void install(byte bArray[], short bOffset, byte bLength)
throws ISOException {
new SimpleApp().register();
}
public void process(APDU arg0) throws ISOException {
byte[] buffer = arg0.getBuffer();
Util.arrayCopyNonAtomic(hello, (short) 0, buffer, (short) 0, (short) 5);
arg0.setOutgoingAndSend((short) 0, (short) 5);
}
}
3-
public class SimpleApp extends Applet {
byte[] hello = { (byte) 'H', (byte) 'e', (byte) 'l', (byte) 'l', (byte) 'o' };;
private SimpleApp() {
}
public static void install(byte bArray[], short bOffset, byte bLength)
throws ISOException {
new SimpleApp().register();
}
public void process(APDU arg0) throws ISOException {
byte[] buffer = new byte[255];
buffer = arg0.getBuffer();
Util.arrayCopyNonAtomic(hello, (short) 0, buffer, (short) 0, (short) 5);
arg0.setOutgoingAndSend((short) 0, (short) 5);
}
}
4-
public class SimpleApp extends Applet {
static byte[] hello = { (byte) 'H', (byte) 'e', (byte) 'l', (byte) 'l', (byte) 'o' };;
byte[] buffer;
private SimpleApp() {
}
public static void install(byte bArray[], short bOffset, byte bLength)
throws ISOException {
new SimpleApp().register();
}
public void process(APDU arg0) throws ISOException {
buffer = arg0.getBuffer();
Util.arrayCopyNonAtomic(hello, (short) 0, buffer, (short) 0, (short) 5);
arg0.setOutgoingAndSend((short) 0, (short) 5);
}
}
5-
public class SimpleApp extends Applet {
static byte[] hello = { (byte) 'H', (byte) 'e', (byte) 'l', (byte) 'l', (byte) 'o' };;
static byte[] buffer;
private SimpleApp() {
}
public static void install(byte bArray[], short bOffset, byte bLength)
throws ISOException {
new SimpleApp().register();
}
public void process(APDU arg0) throws ISOException {
buffer = arg0.getBuffer();
Util.arrayCopyNonAtomic(hello, (short) 0, buffer, (short) 0, (short) 5);
arg0.setOutgoingAndSend((short) 0, (short) 5);
}
}
版本1:缓冲区作为实例变量存储在EEPROM中。 还行吧。
版本2:缓冲区作为类变量存储在EEPROM中。 还行吧。
但是,可能存在一些静态字段的安全性问题,如此处https://community.oracle.com/thread/1752580所述 :
JCRE创建一个上下文,该上下文由属于包的任何应用程序实例共享。 它们被防火墙隔开,因此在其他上下文中的任何应用程序都无法访问。 静态变量和方法不属于实例,而是属于类本身,因此它们不在防火墙的范围内,并且可由智能卡中的任何应用程序访问。 因此,我们面临着严重的安全风险。
或此处: http : //pfa12.free.fr/doc_java/javacard_specifications/specs/jcre/html/JCRESpec06firewall.html (第6.1.6章)
类的实例(对象)由上下文拥有; 类本身不是。 访问类静态字段时,无法执行运行时上下文检查。 调用静态方法时,也没有上下文切换。 (类似地,invokespecial不会引起上下文切换。)
公共静态字段和公共静态方法可从任何上下文访问:静态方法在与其调用者相同的上下文中执行。
静态字段中引用的对象只是常规对象。 它们由创建它们的任何人拥有,并且适用标准防火墙访问规则。 如果有必要在多个上下文中共享它们,则这些对象必须是可共享接口对象(SIO)。
上面的文字并不意味着您完全不能使用静态字段和方法。 您只需要仔细考虑。 另一件事是,对实例的静态引用可能很危险:当您无法删除您的applet时,它们会引起如下情况: http : //askra.de/software/jcdocs/app-notes-2.2.2/garbagecoll .html :
删除小程序意味着删除该小程序及其所有子对象。 如果存在以下任一情况,则删除小程序失败:
applet实例拥有的任何对象都被卡上另一个applet实例拥有的对象引用。
applet实例拥有的任何对象都可以从卡上任何包中的静态字段中引用。
版本3:每个APDU在EEPROM中创建一个新的缓冲区。 一个非常糟糕的主意。 如果没有垃圾收集器,由于缺少EEPROM,您的applet将很快失效。 使用垃圾收集器,您的applet将非常慢。 仅在applet构造函数中或在某个初始“存储数据”阶段分配新实例。
版本4,5:这根本不起作用。 它将导致异常。 您不能将APDU缓冲区引用存储在类或实例变量中:
对APDU缓冲区字节数组的引用不能存储在类变量或实例变量或数组组件中。 有关详细信息,请参见Java Card平台的运行时环境规范,第6.2.2节。
声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.