java一般内存申请有两种:静态内存和动态内存。编译时就能够确定的内存就是静态内存,即内存是固定的,系统一次性分配,比如int类型变量;动态内存分配就是在程序执行时才知道要分配的存储空间大小,比如java对象的内存空间。
有3个是不需要进行垃圾回收的:本地方法栈、程序计数器、虚拟机栈。因为他们的生命周期是和线程同步的,随着线程的销毁,他们占用的内存会自动释放。所以,只有方法区和堆区需要进行垃圾回收,回收的对象就是那些不存在任何引用的对象。
6.CMS算法的过程,CMS回收过程中JVM是否需要暂停
老年代使用CMS垃圾回收器,需要添加虚拟机参数-"XX:+UseConcMarkSweepGC"。
CMS收集器是一种基于"标记-清除"算法实现的收集器,整个过程分为四步
1.初始标记(CMS initial mark),需要暂停所有的工作线程.该过程分为两步:
-
- 标记GC Roots可达的老年代对象
- 遍历新生代对象,标记可达的老年代对象
2.并发标记(CMS concurrent mark)
3.重新标记 (CMS remark)
4.并发清除 (CMS concurrent sweep)
初始标记、重新标记着两个步骤任然需要"Stop The World",初始标记仅仅只是标记一下GC Roots能直接关联到的对象,速度很快,并发标记就是进行GC Roots Tracing 的过程,而重新标记阶段则是为了修正并发标记期间因用户程序继续运行而导致标记产品变动的那一部分对象的标记记录。这个阶段的停顿时间一般会比初始标记阶段稍长一些。,但远比并发标记的时间短。
常见的B/S架构的应用就适合这种收集器,因为其高并发、高响应的特点,CMS是基于标记-清楚算法实现的。
CMS收集器的缺点:
1.对CPU资源非常敏感,在并发阶段虽然不会导致用户停顿,但是会占用CPU资源而 导致应用程序变慢,总吞吐量下降。
2.无法处理浮动垃圾(由于CMS并发清理阶段用户线程还在运行着,伴随着程序的运行自然就还会有新的垃圾不断产生,这一部分产生的垃圾,CMS无法在当次收集中处理掉他们,只要留待下一次GC再进行处理。这一部分产生的垃圾成为"浮动垃圾"),可能出现“Concurrnet Mode Failure”,失败而导致另一次的Full GC。
3.CMS收集器是基于标记-清除算法的实现,因此也会产生碎片。
一旦发生old区满了,并且浮动垃圾未清除完的情况,就会使用Serial Old(单线程,使用的垃圾回收算法是标记-压缩-清理算法)进行垃圾清除,效率极低。
7.JVM有哪些常用启动参数可以调整?