我有一个关于在应用程序内存中存储大量字符串的问题。我需要从文件中加载大约5百万行,每行最多255个字符(url),但大多数是〜50。我有时需要搜索其中一个。是否有可能在~1GB的RAM上运行这个应用程序?
将
ArrayList <String> list = new ArrayList<String>();
工作?
据我所知,java中的String是用UTF-8编码的,这给了我巨大的内存使用量。是否可以使用ANSI编码的字符串来生成这样的数组?
这是使用参数运行的控制台应用程序:
java -Xmx1024M -Xms1024M -jar "PServer.jar" nogui
答案 0 :(得分:10)
默认情况下,最新的JVM支持-XX:+UseCompressedStrings
,它存储仅在内部使用ASCII作为byte []的字符串。
列表中有几GB的文本不是问题,但从磁盘加载可能需要一段时间(很多秒)
如果平均URL是50个字符,这些字符是ASCII,每个字符串有32个字节的开销,则5个条目可以使用大约400 MB,这对于现代PC或服务器来说并不多。
答案 1 :(得分:2)
Java String是一个完整的对象。这意味着appart来自字符串的字符,还有其他信息存储在其中(指向对象类的指针,指向它的指针数量的计数器,以及一些其他基础结构数据)。所以一个空字符串已在内存中占用45个字节(如您所见here)。 现在您只需添加字符串的最大长度并进行一些简单的计算即可获得该列表的最大内存。
无论如何,如果您遇到内存问题,我建议您将字符串加载为 byte [] 。这样你就可以控制编码,你仍然可以进行搜索。
答案 2 :(得分:1)
是否有某些原因需要将其限制为1G?如果你想搜索它们,你肯定不想换到磁盘,但如果机器有更多的内存,那么高于1G是有意义的。
如果您需要搜索,请使用SortedSet
,而不是ArrayList