深入理解Java虚拟机重点

来源:互联网 发布:linux 日志重定向 编辑:程序博客网 时间:2024/06/04 19:32
一、Java虚拟机内存分区
(1)方法区(一般称永久代)
1、所有线程共享的区域
2、主要存放类信息、常量、静态变量、常量池等

(2)虚拟机栈
1、线程私有的内存区域
2、每个方法调用都会创建自己的栈帧,都属于该虚拟机栈
3、栈帧中的局部变量表内存大小在编译期就完成确定,方法运行期间大小不会改变

(3)本地方法栈
1、不同虚拟机有不同的实现、线程私有

(4)堆(一般称新生代)
1、所有线程共享的区域,所占空间最大,用于存放对象实例

(5)程序计数器
1、可看作是字节码的行号指示器,每个线程都会有自己的程序计数器且互不影响,所以是线程私有的内存区域,空间较小
2、当执行native方法时,计数器值为空
3、此区域是唯一一个不会出现OutOfMemoryError情况的内存区域

二、判断对象已死算法
(1)引用计数
1、Java语言未采用该算法,它不能解决循环引用或相互引用的问题

(2)根搜索算法
1、Java和C#都采用这种算法,原理就是作用域搜索,从根开始搜索对象不可达即可回收

三、垃圾回收算法
(1)标记清除算法(可用于老年代)
缺点:效率不高、会产生大量内存碎片

(2)复制算法(主要用于新生代)
原理:将内存分为两块,每次只用一块。用完将活着的对象进行复制
HotSpot虚拟机实现:内存分为三块,一块较大的Eden区和两块较小的Survivor区; 且Eden : Survivor : Survivor = 8:1:1
分配担保策略:如果垃圾回收后存活的对象在另一块Survivor区存不下,将直接在老年代中申请内存

(3)标记整理(标记压缩)算法(可用于老年代)
原理:所有存活对象向一端移动,清理边界外的内存

(4)分代收集算法(一般和其他算法结合使用)

四、垃圾收集器
(1)Serial收集器(新生代)
单线程、工作时会暂停工作线程、简单高效、Client模式的最佳选择

(2)ParNew收集器(新生代)
Serial收集器的多线程版本、Server模式的最佳选择

(3)Parallel Scavenge收集器(新生代)
采用了复制算法、多线程、吞吐量优先

(4)Serial Old收集器(老年代)
单线程、使用标记整理算法、Client模式

(5)Parallel Old收集器(老年代)
多线程、使用标记整理算法

(6)CMS收集器(老年代)
基于标记清除算法

(7)G1收集器(最新)
基于标记整理算法

五、常见虚拟机参数
(1)SurvivorRatio
新生代中Eden区域和Survivor区域容量的比值,默认为8

(2)PretenureSizeThreshold 或 MaxTenuringThreshold
直接晋升到老年代的年龄,大于这个参数直接在老年代分配内存(默认15)

(3)PermSize、MaxPermSize
永久代初始值、永久代的最大值(默认64M)

(4)-Xms、-Xmx
初始堆大小、最大堆大小

(5)NewRatio
永久代和新生代的比值

(6)-Xmn 或 NewSize
新生代大小

(7)GCTimeRatio
吞吐量,默认值99,1/(1+99)=1%,即允许1%的GC时间

(8)MaxNewSize
最大新生代大小

(9)TargetSurvivorRatio

survivor区的可使用率,当该区空间利用率达到该值时,会将对象放到老年代