在我的应用程序中,我每秒都会收到消息,其中包含高度,速度和航向。每次,我收到消息,我需要生成一个符号(jpg)并在桌面应用程序的UI中显示它。以下是我使用的代码。出于某种原因,只要下面的代码集成到应用程序中,我就会一直出现OutOfMemory错误。
为了摆脱它,我把下面的类的实例创建并在一个单独的线程中调用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;
}
}
答案 0 :(得分:1)
java.io.FileReader
类使用流来读取文件。
您的代码从不调用从InputStreamReader
对象上的libraryReader
类继承的close()
方法。
您可以添加finally
块以关闭阅读器或使用try-with-resources
语句 - 可从Java8获得 - 因为FileReader
类实现了AutoCloseable
接口。
最好同时检查有多少线程处于活动状态,因为每次调用convertSVGToJPEG
方法都会创建一个新线程。