JVM详解

java 内存区域

1、方法区

方法区存放的是class对象和字节码指令,当线程执行代码时,就需要用字节码指令了,这个时候就出来了一个程序计数器,。

程序计数器是在方法区之外的内存,存储执行到哪一行的数,很容易理解。

 

2、堆内存

堆内存存放的是new 出来的对象放的区域,但是是如何new出来的呢?过程大致如下,jvm通过方法区的class对象(instanceClass)生产一个instanceOopDesc,这个instanceOopDesc就存放在堆内存中,而这个instanceOopDesc存放的是什么呢?

内容大致如下:

1. 对象头,也叫Mark Word,主要存储对象运行时记录信息,如hashcode, GC分代年龄,锁状态标志,线程ID,时间戳等;
2. 元数据指针,即指向方法区的instanceClass实例
3. 实例数据;
4. 另外,如果是数组对象,还多了一个数组长度

那么到这里我们就知道了,对象.getClass(),其实就是获取到方法取的instanceClass

3、java虚拟机栈

栈桢

进程执行到方法时,就创建一个栈桢,里面存放内容:局部变量表、操作数栈、动态链接、方法出口。

new的对象其实只是存了一个指针。

具体情况如图:

 

 

堆内存的新生代和老年代

大家都知道:新生代存放的都是短期存活的对象,如果这个对象躲过了多个新生代gc(minor GC)之后,就会荣升老年代了。次数是15次

-Xms:java堆内存的大小

-Xmx:堆内存的最大大小

-Xmn:新生代的大小

-XX:PermSize/-XX:MetaSpaceSize:永久代大小

-XX:MaxPermSize/-XX:MaxMetaSpaceSize:永久代最大大小

-Xss:每个线程的栈内存大小

 

新生代和老年代的垃圾回收器

 

新生代垃圾回收器:

ParNew回收器:新生代多线程回收,参数:-XX:UseParNewGC,调节默认线程数:-XX:parallelGCThreads

Serial回收器:新生代单线程回收

G1:

 

老年代垃圾回收器:

CMS回收:并发回收

流程:

1、初识标记:stop the world,然后标记GC Root上的对象(方法的局部变量,类变量),至于该对象内部持有的变量,这里是不管的,所以这个过程非常快

2、并发标记:这个时候允许系统线程工作了,这阶段的工作就是追踪所有对象是否根源上被GC root引用,例如一个存活对象a中的类变量对象b,这个b在第一阶段被标记了,b持有一个c对象,这时c对象就是存活的对象

3、重新标记:再次stop the world,这一阶段两个任务,梳理并发标记过程中 活动过的对象情况,然后给堆中的垃圾对象打上垃圾印记。速度也是很快

4、并发清理:这一步就是把之前已经被标记为垃圾的对象清理掉

 

缺点:是基于标记-整理清理方法,会导致空间碎片。通过参数-XX:UseCMSCompactAtFullCollection参数,会在清理之后再次stop the world 做一下内存整理,速度也是很快。-XX:CMSFullGCBeforeCompaction  指定多少次full GC之后执行这个内存整理

 

因为在并发清理阶段会重新出现垃圾,所以,会预留一部分内存做这部分对象的内存,参数设置:-XX:CMSinitiatingOccpancyFaction,默认值是92%

 

 

 

 

 

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 2
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论 2
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值