javascript - Java UI 线程被阻止 - 内存不足错误

标签 javascript java multithreading

在我的应用程序中,我每秒都会收到消息,其中包含高度、速​​度和航向。每次收到消息时,我都需要生成一个符号 (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;
    }

}

最佳答案

java.io.FileReader类使用流来读取文件。 您的代码永远不会调用 close()libraryReader 对象上的 InputStreamReader 类继承的方法。

您可以添加 finally block 以关闭阅读器或使用 try-with-resources语句 - 从 Java8 可用 - 因为 FileReader 类实现 AutoCloseable界面。

<小时/>

最好检查同时有多少线程处于 Activity 状态,因为每次调用 convertSVGToJPEG 方法都会创建一个新线程。

关于javascript - Java UI 线程被阻止 - 内存不足错误,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/46194157/

相关文章:

javascript - 将 js 代码包装到 .ready() 两次合理吗?

javascript - Foundation Reveal Modal 超出可见区域

java - 更改水平盒节点位置

java - 如何在另一个线程运行时禁用文本框

Javascript在数组中使用构造函数

java - 用于查找节点最可能祖先的图形算法

java - AsyncTask 未运行,logcat 显示为暂停所有线程占用了 : time in ms

c# - 线程的执行上下文

c++ - 多线程C++程序性能不佳

javascript - 我需要向函数添加参数吗?