我描述了一个jdbc / hibernate批处理导入程序。它需要一个csv轻轻地转换它并将其导入到位于localhost的数据库。
令我惊讶的是,操作不是I / O绑定,而是cpu绑定。根据jmx / jconsole以及netbeans profiler,看起来60%的cpu时间花在“老一代”垃圾收集器上 其余用于几何转换(这是合理的)和休眠会话管理。
根据jconsole,其他应用程序使用了大约5-10% 那么对于这样的批量插入任务,cpu / young GC /旧GC的“典型”比率是多少?答案 0 :(得分:1)
百分之六十是真的很高。这通常表明某人使用了大量临时字符串或类似内容。它发生在“老一代”的事实表明它可能正在数据库端发生,可能在等待数据库事务发生时。但这只是一个马背猜测。
您可能希望制作更详细的运行配置文件。
答案 1 :(得分:1)
除了Charlie所说的内容之外,我认为可能导致这种情况的另一件事是,如果你有很多带有终结器的对象(有些库笨拙地做了) - 我记得,这实际上迫使他们快速绕过VM对象释放的路径。
答案 2 :(得分:1)
再看一下netbeans profiler / heap walker,很明显有很多String实例包含完整的sql语句。这是由log4jdbc引起的。 所以Charlie Martins的猜测是部分正确的。
log4jdbc未配置为记录到任何appender,但其日志级别仍设置为INFO。虽然日志文件不包含任何sql信息,但它仍然在后台呈现。
没有log4jdbc的性能提升很大。
数据库cpu%利用率从1-2%上升到20-50%(一个核心充分利用) 之前有5000个条目以批处理模式插入,大约需要100个SECONDS 现在,在大约1-2个SECONDS中插入了5000个条目。
GC现在需要大约6-7%的总CPU时间。
所以我的结论:
答案 3 :(得分:0)
我同意GC时间通常可以达到10%。如果您有旧的gen问题,请尝试添加 - XX:NewSize = 300m参数,您可以在其中增加年轻代。这有助于避免旧区域中大量使用过的对象(垃圾)。特别是当你只有很多本地物品时,你不会故意保留任何东西。