Java面试题

1 JAVA

  2 JVM 虚拟机

 Java 虚拟机由类装载子系统,运行时数据区(内存模型),字节码执行引擎 三部分组成

堆:存放对象:由年轻代与老年代组成 年轻代 分代的唯一理由就是GC性能优化,对象是朝生幕死的,如果分代,将新创建的对象放到年轻代中,当GC的时候先将年轻代进去回收,这样就会腾出很大的空间,

堆大小设置

典型设置:

  • java -Xmx3550m -Xms3550m -Xmn2g -Xss128k
    -Xmx3550m:设置JVM最大可用内存为3550M。
    -Xms3550m:设置JVM促使内存为3550m。此值可以设置与-Xmx相同,以避免每次垃圾回收完成后JVM重新分配内存。
    -Xmn2g:设置年轻代大小为2G。整个JVM内存大小=年轻代大小 + 年老代大小 + 持久代大小。持久代一般固定大小为64m,所以增大年轻代后,将会减小年老代大小。此值对系统性能影响较大,Sun官方推荐配置为整个堆的3/8。
    -Xss128k:设置每个线程的堆栈大小。JDK5.0以后每个线程堆栈大小为1M,以前每个线程堆栈大小为256K。更具应用的线程所需内存大小进行调整。在相同物理内存下,减小这个值能生成更多的线程。但是操作系统对一个进程内的线程数还是有限制的,不能无限生成,经验值在3000~5000左右。
  • java -Xmx3550m -Xms3550m -Xss128k -XX:NewRatio=4 -XX:SurvivorRatio=4 -XX:MaxPermSize=16m -XX:MaxTenuringThreshold=0
    -XX:NewRatio=4:设置年轻代(包括Eden和两个Survivor区)与年老代的比值(除去持久代)。设置为4,则年轻代与年老代所占比值为1:4,年轻代占整个堆栈的1/5
    -XX:SurvivorRatio=4:设置年轻代中Eden区与Survivor区的大小比值。设置为4,则两个Survivor区与一个Eden区的比值为2:4,一个Survivor区占整个年轻代的1/6
    -XX:MaxPermSize=16m:设置持久代大小为16m。
    -XX:MaxTenuringThreshold=0:设置垃圾最大年龄。如果设置为0的话,则年轻代对象不经过Survivor区,直接进入年老代。对于年老代比较多的应用,可以提高效率。如果将此值设置为一个较大值,则年轻代对象会在Survivor区进行多次复制,这样可以增加对象再年轻代的存活时间,增加在年轻代即被回收的概论。

        在JDK1.8开始有了元空间区(Matespace)来替换永久代(Permanent Generation),那么在设置JVM参数的时候,也要增加上Matespace的相关参数了

        minor gc 回收整个年轻代,不是父gc   

        Major GC 只回收老年代

jvm调优的作用:减少gc,最核心减少full gc   STW(stop the word ) 在做gc 时,会停掉用户的所有线程,

oom 内存溢出

老年代放满后,在由s2向老年代存放对象时,会发生full gc,字节码执行引擎会开启一个垃圾回收进程,会对堆的所有内存区域做垃圾回收,如果还说回收不了,就会发送oom 内存溢出

为什么要存在STW: 当进程开始运行后,再进行full gc,将这个进程所关联的gc Root都标记为非垃圾,当full gc还没有完成时,线程完成后,内部的线程栈内存空间都会被释放,这个进程所关联的gc Root又都变成了非垃圾。

可达性分析算法

gc Root跟节点:线程的本地变量,静态变量,本地方法栈的变量,

当堆的Eden区域块满时,字节码引擎在后台开启垃圾收集线程等

找到gc Root ,找到使用gc Root 的直接引用对象,还继续往下搜索引用的对象,找到最后的对象,他的成员变量不在引用其他对象,凡是在这个链条上的所有对象,都会被标成为非垃圾,复制到Survivor的s0中,替他对象都会回(垃圾) ,下一次minor gc 如果还说非垃圾,就会复制到s1中,在经过15此minor gc后,还不是垃圾,就会移到老年代(大对象,如果eden区,放不下直接放入老年代)

对象动态年龄判断:

当一批对象的总大小,大于这块Survivor区域内存大小的50%时,那么此时大于等于这批对象年龄最大值的对象,就可以直接进入老年代,这个规则是希望那些可能长期存货的对象,尽在进入老年代。对象动态年龄判断机制一般在minor gc 之后出发(可能会频繁的出现full gc

        新创建的对象都会被分配到Eden区(一些大对象特殊处理),这些对象经过第一次Minor GC后,如果仍然存活,将会被移到Survivor区。对象在Survivor区中每熬过一次Minor GC,年龄就会增加1岁,当它的年龄增加到一定程度时,就会被移动到年老代中。

        JVM把年轻代分为了三部分:1个Eden区和2个Survivor区(分别叫from和to)。默认比例为8:1,为啥默认会是这个比例

        new出来的对象首先先放到堆中

栈(线程栈)(先进后出):每一个线程运行时,都会产生一些局部变量

                                               每运行到一个方法,都会在栈内开辟一个自己的栈贞方法的独立空间

                  先进后出:先调用的方法(分配内存)会后结束(释放内存),后调用的方法会先结束

                                                  当栈中的局部变量为对象类型,栈指向堆内存 栈中存放的是对象在堆内存中的地址值

                                                  javap  javac

                程序计数器:用来存放程序正在运行或者马上运行的行号或者位置 ,是每一个线程都拥有的  ,为什么要存在程序计数器呢:因为当一个线程正在运行时,有另外一个优先级更高的线程抢走cpu,(前一个线程处于挂去状态)当优先级更高的线程完成时候,cpu需要根据程序计数器的值继续执行前一个程序,字节码执行引擎随着程序的运行动态修改程序计数器

                方法区(元空间):存放常量,静态变量,类信息

                本地方法栈: native修饰的方法,使用c,c++语言

点击高并发:大内存,多cpu系统

minor gc 在处理大内存时,由于内存过大,触发minor gc会耗时多秒,触发minor gc 时会STW,用户发出请求可以会超时

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值