在我的應用程序中,我每秒都會收到包含高度,速度和標題的消息。每次,我都會收到消息,我需要生成一個符號(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'不是類,它是當前實例。這只是寫公共同步無效createSymbolSVG(..'。 – Kayaman