- - PR -
RS232Cを介したデータの読み取り
1
投稿者 | 投稿内容 | ||||
---|---|---|---|---|---|
|
投稿日時: 2006-04-20 19:04
はじめまして.とどろきと申します.
RS232Cを介して,RFIDのリーダライタに命令を送信して, そのレスポンスパケットを取り込むプログラムを作成しています. 問題 RFIDリーダライタに命令を送信 → Streamを使用してレスポンスパケットを取り込む → メモリが増加して,放っておくと"OutOfMemoryError"になってしまう. プログラム概要 @ 「ICタグのIDを読み取る」という命令を,RFIDリーダライタに送り続けます. A 読み取った場合には,そのIDが登録してあるIDかどうかを判断します. B 登録してあるIDの場合は,処理を実行します. C 読み取れなかったor登録してないIDの場合には,@に戻ります. ソース class isoRead { private static CommPortIdentifier ports; private static SerialPort serialPort; private static OutputStream out; private static InputStream in; private static int header = 0xXX, ..., checksum = 0xXX; //命令群 private static String temp1; private static int i, j, read; static void start() { //あるプログラムから呼び出され,start()から始まります String readTag; String arrive = "1901892146007224"; String[] leave = { "562431676007224", "432232071007224","211902261007224"}; //登録してあるID int i, minute; boolean bStop = true; while (bStop) { try { ports = CommPortIdentifier.getPortIdentifier("COM1"); serialPort = (SerialPort) ports.open("RS232C", 1000); serialPort.setSerialPortParams(57600, SerialPort.DATABITS_8, SerialPort.STOPBITS_1, SerialPort.PARITY_NONE); serialPort.setFlowControlMode(SerialPort.FLOWCONTROL_XONXOFF_IN | SerialPort.FLOWCONTROL_XONXOFF_OUT); out = serialPort.getOutputStream(); in = serialPort.getInputStream(); // RFIDリーダライタに命令を送る CommandInventory(out); readTag = ""; // RFIDからのレスポンスを受け取る readTag = Inventory(in); if (readTag != "") { //登録してあるIDであったときの処理 MFTP.ArriveFTP(); } else for (i = 0; i <= 3; i++) { if (readTag.equals(leave[i])) { GFTP.LeaveFTP(); } } } out.close(); in.close(); serialPort.close(); out = null; in = null; serialPort = null; } } catch (Exception e) { System.out.println("Error:" + e.getMessage()); bStop = false; } } } static void CommandInventory(OutputStream rout) { try { rout.write(header);//「IDを読み取る」というコマンドを送信 ・ ・ ・ rout.write(checksum); rout.flush(); } catch (Exception e) { System.out.println("Error:" + e.getMessage()); } } static String Inventory(InputStream rin) { try { temp1 = ""; for (i = 0; i < 23; i++) {//タグを読み取った場合には,レスポンス(23byte)が返ってくる if (i >= 13 && i <= 20) {//レスポンスの13〜20byte目でタグのID情報を取得できる read = rin.read();//IDを1byteずつ取ってきてint型の変数に入れる temp1 = temp1 +Integer.toString(read);//取ってきたIDを繋げたいので,String型に変換 } else { read = rin.read(); } if (read == 13) {//タグを読み取れなかった場合には,2byte目の値が13となる(これはパケット全体の長さ) for (j = 0; j < 11; j++) {//タグを読み取れなかった場合のレスポンスは13byteである.よって2byte目以降を読み取ってくる read = rin.read(); } break; } } } catch (Exception e) { System.out.println("Error:" + e.getMessage()); } return temp1; } } エラー内容は以下の通りです java.lang.OutOfMemoryError: unable to create new native thread at java.lang.Thread.start(Native Method) at com.sun.comm.Win32SerialPort.<init>(Win32SerialPort.java:51) at com.sun.comm.Win32Driver.getCommPort(Win32Driver.java:69) at javax.comm.CommPortIdentifier.open(CommPortIdentifier.java:314) at isoRead.start(isoRead.java:44) at isoKey.main(isoKey.java:90) "readTag = Inventory(in)"の部分をコメントアウトして,レスポンスパケットを受け取りにいかないと,メモリの使用量が受け取りに行く場合に比べ,著しく増加してしまいます.もちろん受け取る場合も,メモリ使用量が増加していきます.また,"CommandInventory(out);"の命令を送る部分をコメントアウトすると,メモリ使用量は増加しません. あくまで私見ですが,RFIDリーダライタからのレスポンスパケットは,一度メモリ上に全て展開されているのではないかと考えています.この問題を解決する方法はありますでしょうか. 自分で試したこと バッファに一度取り込んで,それをファイルに書き出すという方法を試してみたのですが,結果は同じでメモリ使用量が増えていきました. 環境 Windows XP j2sdk1.4.2_11 | ||||
|
投稿日時: 2006-04-21 10:18
CommPortIdentifier.open() の内部でスレッドを作ろうとして失敗しているみたいですね。
ループの外でポートをオープンしておいて再利用する方法はいかがでしょうか? | ||||
|
投稿日時: 2006-04-21 14:59
>インギ様
ご回答ありがとう御座います.
上記の通り,ループの外でポートをオープンしてみたところ,メモリ使用量の増加は抑えられました.ご助言いただき,本当に助かりました. 念のため,修正済のソースを下に提示します. try { ports = CommPortIdentifier.getPortIdentifier("COM1"); serialPort = (SerialPort) ports.open("RS232C", 1000); serialPort.setSerialPortParams(57600, SerialPort.DATABITS_8, SerialPort.STOPBITS_1, SerialPort.PARITY_NONE); serialPort.setFlowControlMode(SerialPort.FLOWCONTROL_XONXOFF_IN | SerialPort.FLOWCONTROL_XONXOFF_OUT); } catch (Exception e) { System.out.println("Error:" + e.getMessage()); } while (bStop) { //while文開始 |
1