【问题标题】:Effectively retrieving BLOB XML from database using Java使用 Java 从数据库中有效地检索 BLOB XML
【发布时间】:2016-02-12 05:22:54
【问题描述】:

我正在尝试使用以下 sn-p 从 Sun Identity Manager 数据库中读取 XML 文件详细信息

            String xmlTxt="";
            ArrayList<String> xmlList = new ArrayList<String>();
            BLOB blob=null;
            OracleConnection conn=null;
            OraclePreparedStatement stmt = null;
            OracleResultSet rs = null;
            GZIPInputStream gStream = null;
            log.debug("Initializing DB connection...");

                try {
                Class.forName("oracle.jdbc.driver.OracleDriver");
                conn=(oracle.jdbc.OracleConnection)DriverManager.getConnection(dbURL, dbUserName, dbPassword);           
                stmt = (OraclePreparedStatement) conn.prepareCall("SELECT XML FROM TASK WHERE TYPE='WorkItem'");
                rs = (OracleResultSet) stmt.executeQuery();

                    while(rs.next()){
                        blob = rs.getBLOB(columnLabel);
                    if(!blob.isEmptyLob())
                        gStream = new GZIPInputStream(blob.getBinaryStream());
                    if(gStream.available()>0)
                        xmlTxt = IOUtils.toString(gStream,columnEncoding);                          
                        xmlList.add(xmlTxt);
                    }
                }
                catch(ClassNotFoundException cnf){
                    //Handle errors for Class.forName
                    log.error("ClassNotFoundException " + cnf.getMessage());
                    log.error("ClassNotFoundException " + cnf);     
                }
                catch (SQLException se) {
                //Handle errors for JDBC
                log.error("SQLException " +se.getMessage());
                log.error("SQLException " + se);
                }
                catch (IOException ie) {
                //Handle errors for I/O
                log.error("IOException " +ie.getMessage());
                log.error("IOLException " + ie);
                }
                catch (OutOfMemoryError E){
                    log.error("OutOfMemoryError Encountered :"+ Runtime.getRuntime().totalMemory());
                }
                finally{
                    try {
                        if(rs!=null)
                        rs.close();
                        if(stmt!=null)
                        stmt.close();
                        if(blob!=null)
                        blob.free();
                        if(conn!=null)
                        conn.close();
                        } 
                    catch (SQLException se) {
                        //Handle errors for JDBC
                        log.error("SQLException during close " +se.getMessage());
                        log.error("SQLException during close" + se);
                        }
                }
                log.debug("End of DB Operation");               
            return xmlList;

目前我正在我们的开发环境中对其进行测试,其中记录为 100 条,每个 blob 数据的平均大小为 2 MB。当总记录稳定增加时,我还可以看到堆大小的消耗是巨大的。我当前的 Java 堆大小是 Xmx512m -Xms64m,在生产中我们有近 150 万条记录要处理,所以想知道需要多少堆大小。

我通常会在下面一行出现内存不足错误

xmlTxt = IOUtils.toString(gStream,columnEncoding);

https://commons.apache.org/proper/commons-io/apidocs/org/apache/commons/io/IOUtils.html

请告知我们是否有其他更好的方法可以优化代码以提高性能。

【问题讨论】:

  • 您正在将数据库表的全部内容流式传输到内存中。因此,优化代码的一种方法是,嗯,不要那样做。
  • 回答关于 prod 需要多少堆空间的问题:我估计它会在 3000GB 左右。
  • 嗯.. 但是我在 BLOB 列中只有我需要的所有数据,所以无论如何都必须检索它并使用我们的业务逻辑处理它......
  • 这与一个 BLOB 无关。这是关于将其中的一百万个可能存储在一个列表中 (xmlList)。你不能以流的方式实现你的逻辑吗?
  • 谢谢罗比。我可以为整个项目使用流选项更改我的逻辑,这在更大程度上减少了堆大小:-)

标签: xml database apache blob jdom-2


【解决方案1】:

以流方式解析表中的数据,而不是将其作为字符串/数组列表复制到内存中。

【讨论】:

    猜你喜欢
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2016-05-28
    • 1970-01-01
    • 2011-09-09
    相关资源
    最近更新 更多