Java面试题整理四(GC和内存)

        这一次提笔写博客倒不是为了整理面试中遇到的问题,而是在实际工作中遇到了这个问题,于是想把记录下来。

这次遇到的问题是GC内存使用溢出的问题,由于它也是面试时经常问到的题目。(到现在都记得在百度面试时被问懵逼了,自以为平时开发遇不到这样的问题所以什么都没看就去了~~~~)

       下面先看看我遇到的问题吧!

场景:本公司准备搭建自己的数据仓库,于是需要使用ETL工具Kettle(现改名Spoon,基于JVM运行。)来完成数据的迁移,清洗工作。具体的迁移和清洗任务这里就不详细说明了。

问题:在完成一部分Job编写后进行Cart服务器部署,但是使用实际数据(一天的数据量)运行时却提示“GC overhead limited executed”。接下来百度时就是各种看不懂的参数,如:-Xms,-XmX,-mx等等。

        OK,场景和问题都讲清楚了,下面先看看今天的这几主角分别是什么意思和名字来源。

名词及参数解释(不做详细描述,后面再具体详述):

       GC(gabage collection):这是java虚拟机的一种垃圾自动判断出并收集的机制,但一般不会立即释放它们的内存空间,当然也可以通过调用 System.gc()方法,来强制垃圾回收,但是要注意的是内存并不是立即释放的。

       Heap:堆

       Stack:栈

       -vmargs -Xms128M -Xmx512M -XX:PermSize=64M -XX:MaxPermSize=128M

       -vmargs:表示后面是JVM的参数。

       -Xms128m: 设置JVM初始内存为128m。此值通常与-Xmx相同,以避免每次垃圾回收完成后JVM重新分配内存。

       -Xmx512m:设置JVM实例 最大可用内存为512M。

       -XX:PermSize=64M:JVM初始分配的 非堆 内存

       -XX:MaxPermSize=128M:JVM最大允许分配的非堆内存,按需分配

       -Xmn192m:设置 年轻代 大小为192m。整个 JVM内存=年轻代 + 年老代 + 持久代

       持久代一般固定大小为64m,所以增大年轻代后,将会减小年老代大小。此值对系统性能影响较大,Sun官方推荐配置为整个3/8。。

-Xss128k:设置每个线程堆栈大小。

        JDK5.0以后每个线程堆栈大小为1M(之前为256K),可以根据应用中的线程所需进行调整。在相同物理内存下,减小这个值能执行更多的线程。但是操作系统对一个进程内的线程数还是有限制的,一般在3000~5000左右。

        参数调优建议:

       (1)增加Heap的大小(-Xmx)虽然会降低GC的频率,但也增加了每次GC的时间。并且GC运行时,所有的用户线程将暂停,不做任何工作。
       (2)Heap大小并不等于进程的内存使用量。进程的内存使用量要大于-Xmx定义的值,因为Java为其他任务分配内存,例如每个线程的Stack等。
      (3)Server端JVM最好将-Xms和-Xmx设为相同值。建议-Xmn值约等于-Xmx的1/3(或者3/8)。
      (4)一个应用程序最好是每10到20秒间运行一次GC,每次GC在半秒之内完成。

       以下讲三个内容来帮助理解,分别是JVM中内存分配,GC原理,Java应用运行流程

       一、JVM中内存分配

       Java 虚拟机具有一个堆,堆是运行时数据区域,所有类实例和数组的内存均从此处分配。堆是在 Java 虚拟机启动时创建的。在JVM中堆之外的内存称为非堆内存(Non-heap memory)

未完待续···

 

 

 

 

 

 

你可能感兴趣的:(学习笔记)