为什么我的JDBC调用占用的内存是实际数据大小的4倍

Pra*_*hra 5 java jdbc

我写了一个小的java程序,它使用简单的JDBC调用从DB2数据库加载数据.我正在使用select查询获取数据并使用java语句来实现此目的.我有正确关闭的语句和连接对象.我使用64位JVM进行编译和运行程序.

该查询返回了5200条记录,每行有24列,这需要我大约4分钟来加载Unix中的完整数据(具有多处理器环境).我使用HashMap作为数据结构来加载数据:Map<String, Map<String, GridTradeStatus>>.bean GridTradeStatus是一个简单的getter/setter bean,里面有24个属性.

程序所需的内存非常高.Java堆大小上升到5.8 - 6GB以加载完整数据,而实际使用的堆大小保持在4.7 - 4.9GB之间.我知道我们不应该将这么多数据加载到内存中,但我的业务需求只是这样.

问题是,当我将我的表的整个数据放在一个平面文件中时,它大约相当于~1.2GB.我想知道为什么我的java程序消耗的内存是实际大小的4倍.

Dur*_*dal 1

这里没有什么令人惊讶的(至少对我来说)。

a.) 与最常见的文本格式相比,java 中的字符串消耗的空间增加了一倍(因为字符串在堆中始终表示为 UTF-16)。另外,String 作为一个对象有相当多的开销(String 对象本身、对其包含的 char[] 的引用、hashCode 等)。对于小字符串,String 对象消耗的内存与其包含的数据一样多。

b.) 将内容放入 HashMap 中。HashMap 并不完全具有内存效率。首先,它使用默认的负载系数 75%,这意味着具有许多条目的映射也有一个大桶数组。然后,映射中的每个条目本身就是一个对象,这至少需要两个引用(键和值)加上对象开销。

总之,您几乎必须预期内存需求会增加相当多。如果平均数据字符串相对较短,则因子 4 是合理的。