私のアプリケーションでは、高度、速度、見出しを含む1秒ごとにメッセージが表示されます。メッセージが表示されるたびに、シンボル(jpg)を生成してデスクトップアプリケーションのUIに表示する必要があります。以下は、私が使用したコードです。何らかの理由で、以下のコードがアプリケーションに統合されるとすぐに、OutOfMemoryエラーが発生します。Java UIスレッドがブロックされました - メモリ不足エラー
これを取り除くために、私はインスタンス作成をクラスの下に置き、別のスレッドでcreateSymbolを呼び出し、svgを別のスレッドへのjpg変換にしました。それでも問題は解決されません。このコードは毎秒実行されるので、私は考えています。メモリにjavascriptライブラリmilsymbol.jsを読み込むと、この問題が発生します。
私の質問には、私の理解は正しいですか?あなたが考える問題は何か?
私の理解が正しい場合、方法はありますか?私は一度メモリに一度だけ読み込むことができますし、毎回、既にロードされているライブラリを参照して関数を呼び出すことができますか?
以下のコードに関して改善点はありますか?
public class SymbolCreation {
private static final Logger log =
Logger.getLogger(UAVSymbolCreation.class);
int altitude;
int heading;
int speed;
public SymbolCreation(int altitude, int speed, int heading) {
this.altitude = altitude;
this.heading = heading;
this.speed = speed;
}
public void createSymbol() {
synchronized(this) {
File milSymbolLib = new File("config/4586controller/milsymbol.js");
if(milSymbolLib.exists()) {
try {
Reader libraryReader = new FileReader(milSymbolLib);
ScriptEngine scriptEngine = new ScriptEngineManager().getEngineByName("JavaScript");
scriptEngine.eval(libraryReader);
SymbolCreation symbolCreation = this;
scriptEngine.put("symbolCreation",symbolCreation);
scriptEngine.eval("function run(symbolCreation){var altitude = symbolCreation.getAltitude(); "
+ "var speedVal = symbolCreation.getSpeed(); "
+ "var heading = symbolCreation.getHeading();"
+ "symbolCreation.createSymbolSVG(new ms.Symbol('SFA-MFQ--------',{size:20, altitudeDepth:altitude, speed: speedVal , direction: heading}).asSVG());} run(symbolCreation);");
} catch (FileNotFoundException e) {
// TODO Auto-generated catch block
e.printStackTrace();
} catch (ScriptException se) {
se.printStackTrace();
}
}
}
}
public void createSymbolSVG(String svgStr) {
synchronized(this) {
boolean fileCreated = false;
File svgFile = new File("config/4586controller/symbol.svg");
if(!svgFile.exists()) {
try {
fileCreated = svgFile.createNewFile();
} catch (IOException e) {
// TODO Auto-generated catch block
e.printStackTrace();
}
} else {
fileCreated = true;
}
try {
if(fileCreated) {
List<String> lines = Arrays.asList(svgStr);
Path svgFilePath = Paths.get(svgFile.getPath());
Files.write(svgFilePath, lines, Charset.forName("UTF-8"));
//Conversion will happen on an individual thread - COMMENTED OUT
convertSVGToJPEG(svgFile);
}
} catch (IOException ioe) {
ioe.printStackTrace();
}
}
}
public void convertSVGToJPEG(final File svgFile) {
synchronized(this) {
Runnable svgToJPEGConversion = new Runnable() {
public void run() {
try {
// TODO Auto-generated method stub
//NOw convert svg to jpg
String svg_URI_input = svgFile.toURI().toString();
TranscoderInput input_svg_image = new TranscoderInput(svg_URI_input);
//Step-2: Define OutputStream to JPG file and attach to TranscoderOutput
File jpgFile = new File("config/4586controller/uav.jpg");
if(jpgFile.exists()) {
jpgFile.createNewFile();
}
OutputStream jpg_ostream = new FileOutputStream(jpgFile);
TranscoderOutput output_jpg_image = new TranscoderOutput(jpg_ostream);
// Step-3: Create JPEGTranscoder and define hints
JPEGTranscoder my_converter = new JPEGTranscoder();
my_converter.addTranscodingHint(JPEGTranscoder.KEY_QUALITY,new Float(.9));
// Step-4: Write output
my_converter.transcode(input_svg_image, output_jpg_image);
// Step 5- close/flush Output Stream
jpg_ostream.flush();
jpg_ostream.close();
} catch (IOException ioe) {
ioe.printStackTrace();
} catch (TranscoderException te) {
te.printStackTrace();
}
}
};
Thread imageConversionThread = new Thread(svgToJPEGConversion);
imageConversionThread.start();
}
}
public int getAltitude() {
return altitude;
}
public int getHeading() {
return heading;
}
public int getSpeed() {
return speed;
}
}
なぜメソッドを同期させるのではなく、どこでも 'synchronized(this)'を使用していますか? – Kayaman
インスタンスの代わりにクラスにロックを適用したいからです。スレッドごとに新しいインスタンスを作成するためです。なぜなら、私はこのメソッドに作用する異なるインスタンスを作ることができないからです。私は、メッセージが来るとシンボルの作成を逐次的にしたいと思っています。 – User
しかし、 'this'はクラスではなく、現在のインスタンスです。 'public synchronized void createSymbolSVG(..'。 – Kayaman