2015-08-27 115 views
1

我有一个格式地图存储在一个文件中。 此文件有超过100,000条记录。字符串和Permgen内存

每个条目的值接近10k。

我在内存中加载1000条记录到地图中,处理它们,然后清除地图并加载下一个1000条记录。

我的问题是:

  1. 由于字符串存储在字符串池是在PermGen的 内存区域,当我清除地图将字符串中的垃圾收集 ?

  2. 如果他们不是垃圾收集有没有办法强制 他们被垃圾收集?

  3. 是否有任何保证,如果程序运行内存不足 ,JVM会在抛出OutOfMemory之前清除permGen内存 异常?

+0

看来你能够将任意“记录”块加载到内存中......所以我想知道两个想法:为什么东西存储在地图中很重要;另一件事是:如果你关心内存使用情况;你为什么不用更小的块?或者相反:您是否已经完成了一些分析并发现使用1000个结果进行最佳性能分析? – GhostCat

+0

@Jagermeister:最初的条目大约为20,000,并且它们完全加载到地图中并进行处理。但是展望结果竟然超过了10万。为了处理这些问题,我收到了内存不足异常。所以我简要介绍了什么占据了太多的空间。 Char占据了超过50%的空间。所以想到了批量阅读条目。当它与速度与内存权衡相比时,1000似乎是一个很好的数字。 – sujith

+0

@sujith - 您使用的是哪个版本的java? – TheLostMind

回答

4

好。让我们开始....

由于字符串存储在字符串池是在PermGen的内存 区域,当我清除地图将字符串被垃圾收集?

所有字符串都不存储在字符串常量池中。只有实际的字符串和字符串文字才会进入字符串常量池。在java-8中没有permgen的概念。 Metaspace已经(几乎优雅地)取代了Permgen

如果你从一个文件中读取字符串(没有被拦截),那么你的字符串会被GCed。如果你有字符串文字(如果你做..:P,上帝保存你),当装入定义这些字符串的类的类加载器获取GCed时,它们将被GCed。

如果他们不是垃圾收集有没有办法强制 他们被垃圾收集?

那么,你总是可以明确地呼叫System.gc()(在生产环境中不是一个好主意)。如果您使用的是java-8,请使用G1Gc并启用String deduplication

是否有任何保证,如果程序运行内存, JVM会抛出内存溢出 异常

GC将尽力清理一样,因为它前清理PermGen的内存能够。不,不能保证会发生这种情况。

+0

我不理解这部分“\t 如何才能在文件中的字符串被拦截或不被拦截?只要内容没有加载到内存中,我们如何区分字符串的文件作为被拦截的或不是? 另外,即使String是使用String s = new String(“xyz”)创建的,如果它尚未存在于permgen中,则会创建一个String对象,并将“xyz”放置在permgen中。因此,在这种情况下,如果GC运行堆中的String对象,将会收集垃圾,但字符串池中的条目仍然存在。是否错误? – sujith

+0

@sujith - 如果您正在从文件读取字符串,不会被拦截是的,如果GC运行的话你是对的,那么它可能不会收集常量池 – TheLostMind

+0

中的字符串,谢谢y ou提供有关java 8功能的信息。我会尝试这个解决方案。我还有一个问题 。假设我有两个字符串 字符串one =“hello world”字符串two =“hello”字符串three =“hell” 现在,当这些被拦截时,会在String pool中创建3个字符串还是由于String的内容两个和三个字符串是一个字符串的子字符串,将只有一个字符串池中的三个字符串具有不同的偏移量的字符集? – sujith