相关疑难解决方法(0)

java.lang.OutOfMemoryError:超出了GC开销限制

我在一个程序中得到这个错误,该程序创建了几个(几十万个)HashMap对象,每个对象有几个(15-20)个文本条目.在提交到数据库之前,必须收集这些字符串(不会分解成较小的数量).

根据Sun的说法,如果在垃圾收集中花费了太多时间,则会发生错误:如果超过98%的总时间花在垃圾收集上,并且不到2%的堆被恢复,则会抛出OutOfMemoryError. ".

显然,可以使用命令行将参数传递给JVM

  • 通过"-Xmx1024m"(或更多)增加堆大小,或
  • 通过"-XX:-UseGCOverheadLimit"完全禁用错误检查.

第一种方法工作正常,第二种方法在另一个java.lang.OutOfMemoryError中结束,这次是关于堆的.

所以,问题:对于特定的用例(即几个小的HashMap对象),是否有任何编程替代方案?例如,如果我使用HashMap clear()方法,问题就会消失,但HashMap中存储的数据也会消失!:-)

StackOverflow中的相关主题也讨论了该问题.

java heap heap-memory hashmap g1gc

317
推荐指数
10
解决办法
59万
查看次数

如何估计JVM是否有足够的可用内存用于特定数据结构?

我有以下情况:有几台机器组成一个集群.客户端可以加载数据集,我们需要选择将加载数据集的节点,如果没有一台机器可以适合数据集,则拒绝加载/避免OOM错误.

我们当前所做的事情:我们现在entry count在数据集中估算memory to be usedas entry count * empirical factor(手动确定).然后检查它是否低于空闲内存(得到Runtime.freeMemory()),如果是,则加载它(否则重做其他节点上的进程/报告没有空闲容量).

这种方法的问题是:

  • empirical factor需要被重新和手动更新
  • freeMemory有时可能会因为一些未清理的垃圾而少报(这可以通过System.gc在每次这样的通话之前运行来避免,但这会减慢服务器的速度并且还可能导致过早的促销)
  • 另一种方法是"只是尝试加载数据集"(如果抛出OOM则返回)但是一旦抛出OOM,你可能会破坏在同一个JVM中运行的其他线程,并且没有优雅的方法从中恢复.

这个问题有更好的解决方案吗?

java memory-management out-of-memory

12
推荐指数
1
解决办法
380
查看次数

调整GC用于Java音频应用程序

我注意到在java中播放音频时,gc中的MarkSweepCompact阶段太长并导致短暂的静音,这是不可接受的.所以我需要使用低暂停gc.我尝试过Parallel和CMS,它们似乎工作得更好,因为我认为暂停时间更短,并且它们不会像默认那样经常完全收集.

到目前为止,我已经使用ParallelGC的以下选项测试了我的程序:

-XX:+UseParallelGC 
-XX:MaxGCPauseMillis=70
Run Code Online (Sandbox Code Playgroud)

对于ConcurrentMarkSweep:

-XX:+UseConcMarkSweepGC
-XX:+CMSIncrementalMode
-XX:+CMSIncrementalPacing
Run Code Online (Sandbox Code Playgroud)

我也尝试过G1GC,但它仍然在java 6中实验性.两种模式的选项:

-Xms15m
-Xmx40m
-XX:+UnlockExperimentalVMOptions
-XX:+CMSClassUnloadingEnabled
-XX:+TieredCompilation
-XX:+AggressiveOpts
-XX:+UseAdaptiveSizePolicy
-Dsun.java2d.noddraw=false
-Dswing.aatext=true
-XX:MaxPermSize=25m
-XX:MaxHeapFreeRatio=10
-XX:MinHeapFreeRatio=10
Run Code Online (Sandbox Code Playgroud)

哪种GC在这种情况下更好?是否可以针对最佳CPU性能和最小内存使用量对这些设置进行优化?

编辑为了识别暂停,我记录了将音频数据写入输出线的时间,通常在92到120毫秒之间(我写的是16384字节= ~92毫秒),广告在运行全GC时,它是200+毫秒:

65.424: [Full GC (System) [PSYoungGen: 872K->0K(2432K)] [PSOldGen: 12475K->12905K(16960K)] 13348K->12905K(19392K) [PSPermGen: 15051K->15051K(22272K)], 0.2145081 secs] [Times: user=0.20 sys=0.00, real=0.21 secs] 
Was writing 16384 bytes, time to write 263 ms
Run Code Online (Sandbox Code Playgroud)

EDIT2我的应用程序的分配模式如下:它在启动时加载一堆对象,然后它开始播放,我猜之后的大多数对象都由gui分配,因为凝视/暂停音频不会改变GC图形许多.这是visualgc与并行gc一起显示的内容: 替代文字

图表在启动时开始,我开始播放.标记是

1)声音延迟和完整的gc,我认为它增加了旧尺寸:

101.646: [Full GC [PSYoungGen: 64K->0K(6848K)] [PSOldGen: 15792K->12773K(19328K)] 15856K->12773K(26176K) [PSPermGen: 15042K->14898K(23808K)], 0.2411479 secs] [Times: user=0.19 sys=0.00, real=0.24 secs]
Run Code Online (Sandbox Code Playgroud)

2)我打开应用程序窗口并暂停播放.什么都没有改变,稍后它增加了伊甸园的大小.

3)我打开窗口再次开始播放.

所以我需要增加分配的旧Gen大小?我怎么做?我正在使用-XX:NewRatio = 10和-XX:NewSize = …

java audio performance garbage-collection

7
推荐指数
1
解决办法
1944
查看次数

Java CMS GC行为

我有一个导致创建大量垃圾的应用程序.第一个(和几乎一个)标准是低GC暂停时间.我使用visualgc工具(和gc日志)尝试不同的GC参数.最佳参数如下.

-XX:+ UseConcMarkSweepGC

-Xmx1172M

-Xms600M

-XX:+ UseParNewGC

-XX:新尺寸= 150M

我的应用程序在带有Java 1.6.0_21的SunOS 10上运行.硬件是2 x CPU四核(uname -X结果是numCPU = 8).

问题是

观察GC行为,在伊甸园空间上创建新对象,直到伊甸园已满.当eden space full GC运行时,清除垃圾,如果对象不是死复制到Old-gen(我丢弃'从'&'到'空格),同样Old-Gen已满,GC运行与CMS并发阶段并清除旧-gen空间.CMS的某些部分是Stop-the-world(暂停时间).这是一个循环.

  1. 以上场景是真的吗?
  2. 在GC清理旧的gen空间后,没有足够的空间扩展旧的gen空间(XMS和XMS值不同)?
  3. 完全GC操作开始时?怎么决定呢?
  4. CMS并发阶段持续时间取决于Eden空间大小,实际上我的期望是,Eden空间不会影响CMS并发阶段持续时间.GC与CMS并发阶段的eden空间有什么关系?
  5. 还有什么建议我最小化暂停时间?的确,对我来说最有价值的答案:)

谢谢

java garbage-collection

6
推荐指数
1
解决办法
1万
查看次数