我的程序速度不够快,但我宁愿放弃内存优化的速度,因为一个用户的最大内存使用量可达300 MB,这意味着它们中的很少一些可能会不断地使应用程序崩溃。我发现的大部分答案都与速度优化有关,其他只是一般(“如果你直接从数据库写入内存,应该没有太多的内存使用量”)。好吧,似乎有:)我正在考虑不发布代码,所以我不会“锁定”某人的想法,但另一方面,如果你没有看到我已经完成的工作,我可能会浪费你的时间所以在这里,它是:在Java中将数据库写入(zip)文件的最有效的方法是什么?
// First I get the data from the database in a way that I think can't be more
// optimized since i've done some testing and it seems to me that the problem
// isn't in the RS and setting FetchSize and/or direction does not help.
public static void generateAndWriteXML(String query, String oznaka, BufferedOutputStream bos, Connection conn)
throws Exception
{
ResultSet rs = null;
Statement stmt = null;
try
{
stmt = conn.createStatement(ResultSet.TYPE_SCROLL_INSENSITIVE, ResultSet.CONCUR_READ_ONLY);
rs = stmt.executeQuery(query);
writeToZip(rs, oznaka, bos);
} finally
{
ConnectionManager.close(rs, stmt, conn);
}
}
// then I open up my streams. In the next method I'll generate an XML from the
// ResultSet and I want that XML to be saved in an XML, but since its size takes up
// to 300MB, I want it to be saved in a ZIP. I'm thinking that maybe by writing
// first to file, then to zip I could get a slower but more efficient program.
private static void writeToZip(ResultSet rs, String oznaka, BufferedOutputStream bos)
throws SAXException, SQLException, IOException
{
ZipEntry ze = new ZipEntry(oznaka + ".xml");
ZipOutputStream zos = new ZipOutputStream(bos);
zos.putNextEntry(ze);
OutputStreamWriter writer = new OutputStreamWriter(zos, "UTF8");
writeXMLToWriter(rs, writer);
try
{
writer.close();
} catch (IOException e)
{
}
try
{
zos.closeEntry();
} catch (IOException e)
{
}
try
{
zos.flush();
} catch (IOException e)
{
}
try
{
bos.close();
} catch (IOException e)
{
}
}
// And finally, the method that does the actual generating and writing.
// This is the second point I think I could do the memory optimization since the
// DataWriter is custom and it extends a custom XMLWriter that extends the standard
// org.xml.sax.helpers.XMLFilterImpl I've tried with flushing at points in program,
// but the memory that is occupied remains the same, it only takes longer.
public static void writeXMLToWriter(ResultSet rs, Writer writer) throws SAXException, SQLException, IOException
{
//Set up XML
DataWriter w = new DataWriter(writer);
w.startDocument();
w.setIndentStep(2);
w.startElement(startingXMLElement);
// Get the metadata
ResultSetMetaData meta = rs.getMetaData();
int count = meta.getColumnCount();
// Iterate over the set
while (rs.next())
{
w.startElement(rowElement);
for (int i = 0; i < count; i++)
{
Object ob = rs.getObject(i + 1);
if (rs.wasNull())
{
ob = null;
}
// XML elements are repeated so they could benefit from caching
String colName = meta.getColumnLabel(i + 1).intern();
if (ob != null)
{
if (ob instanceof Timestamp)
{
w.dataElement(colName, Util.formatDate((Timestamp) ob, dateFormat));
}
else if (ob instanceof BigDecimal)
{
// Possible benefit from writing ints as strings and interning them
w.dataElement(colName, Util.transformToHTML(new Integer(((BigDecimal) ob).intValue())));
}
else
{ // there's enough of data that's repeated to validate the use of interning
w.dataElement(colName, ob.toString().intern());
}
}
else
{
w.emptyElement(colName);
}
}
w.endElement(rowElement);
}
w.endElement(startingXMLElement);
w.endDocument();
}
编辑:这里是存储器的使用(与VisualVM的采取)的一个例子:
EDIT2:数据库是Oracle 10.2.0.4。并且我已经设置了ResultSet.TYPE_FORWARD_ONLY并获得了最多50MB的使用量!正如我在评论中所说的那样,我会密切关注这一点,但它确实很有希望。
EDIT3:似乎有可用另一种可能的优化。正如我所说,我正在生成一个XML,这意味着大量的数据会重复(如果没有其他的话,那么标签),这意味着String.intern()可以帮助我,我会在测试时回复。
你能解决这个格式吗? – whiskeysierra 2010-09-14 07:21:52
不知道你在什么时候看到它,当它被张贴它被打破,所以我redid它。如果还不够好,建议执行什么操作:) – Andrija 2010-09-14 07:24:18
我没有读取所有代码,但我知道您正试图将一些关系数据转换为XML并将其存储在您的zip文件中。你能绕过java吗?一些RDBMS系统导出2 xml。然后你只需压缩文件。 – emory 2010-09-14 07:34:01