我正在监视在Jvm 6
上运行的Java应用程序。
这是jvisualVM面板1的屏幕截图。
我注意到当堆大小很小时(图片中的12:39之前),垃圾收集器经常运行。 然后我运行一次内存昂贵的任务几次(从12:39到12:41)并且堆空间增长。为什么从那时起垃圾收集器的运行频率较低?
一小时或更长时间后,如果我避免在应用程序上执行昂贵的任务,堆空间会慢慢减少。 为什么使用的堆空间需要很长时间才能减少?
我能做些什么来避免这种行为吗? 新的Java8 VM是否有不同的行为?
答案 0 :(得分:2)
我能做些什么来避免这种行为吗?
设置-XX:MaxHeapFreeRatio=30 -XX:MinHeapFreeRatio=15
,这会更积极地缩小堆大小。请注意,并非所有GC实现都会产生不用于操作系统的内存。至少G1会这样做,但这在java 6上不可用。
答案 1 :(得分:1)
行为看似正常。
在您附加的个人资料快照中,直到12:39,还没有很多GC正在进行。
然后您运行您的任务,并且当不再可访问的对象符合GC条件时,扫描会标记它们并将其删除。
除非由于某些内存泄漏导致频繁崩溃和频繁崩溃,否则您不一定需要担心堆的大小。 GC将负责从堆中删除符合条件的对象,并且您在影响GC方面受到限制(当然,除非您切换GC实现)。
平台的每个主要版本都包含一些JVM和GC更改/改进,但应用程序的行为在Hotspot 7/8中将非常相似。试试吧。
现代JVM具有高度优化的垃圾收集器,您不必担心它何时/何时回收内存,而是更多关于确保释放对象以使其符合收集条件的要求。启动后多久会遇到内存不足的问题?
如果由于内存不足而导致崩溃,请将JVM配置为在退出时进行堆转储: -XX:+ HeapDumpOnOutOfMemoryError -XX:HeapDumpPath = date.hprof