jvm内存概念、原理及调优

好久没有更新了,最近即将学完java基础部分,企业对java开发基础知识关注最多的时候jvm和映射这两块,这篇主要总结我学习到的部分与大家分享,下篇更新映射种类及底层源码的大致实现思路。
一、jvm分为五块:
1、方法区(hotspot中也称为堆的持久代,这种分类较少使用):用于存储类的字节码信息,常量池,所有线程共享,其中常量池又分为以下两种:
自定义常量池:程序员定义的static final常量
字面量:分为五种,字符串、字符、数字、boolean值、null。(jdk1.8后字符串常量池移入堆中)
2、堆(最为重要),分为新生代younggeneration和老生代oldgeneration,其中新生代又分为伊甸园eden区和辛存者survivor区,用于分带存储回收对象数据,gc的主要工作区域。堆是所有线程共享的。
3、栈stack,每新建一个线程就开辟一个栈,通过分配栈帧记录线程中方法的变量及返回值,注意栈是先进后出的,栈是线程独有。
4、本地方法区native,执行更快,这里的方法是用java语言声明的,但用操作系统底层语言执行的,本地方法区是线程独有的。
5、寄存器(或者叫计数器)pc counter,用于存储和调度线程的指令,一个线程逻辑执行先后顺序是靠指令实现的,jvm会自动进行各线程间指令调优重排序,程序员可以声明volatile变量禁止重排序,确保变量每次被读取的是最新值,不被脏读,寄存器是线程独有的。


二、GC工作机制
方法区空间较大,需要存储的信息很难占满,java语言规范也没有要求gc回收方法区,一般而言是不需要考虑的,只有废弃的常量和无用的类可以回收,注意是“可以”,不是一定执行的。gc工作机制主要围绕堆的垃圾回收展开:

垃圾标记有两种方式:
引用计数法:通过对象被引用次数进行计数,标记为0的不被引用将被回收,但是存在两个无用对象相互引用无法识别的问题。

寻根标记法:通过搜寻根对象引用路径,找出并标记未被引用的对象,有效识别相互引用的问题。

堆的垃圾回收主要有三种方式:
标记清除markclearning:直接删除被标记为垃圾的对象,效率较高但是会产生内存碎片
标记复制copying:通过将一块内存空间平均分为2块,复制有用对象到空白区域有序排列占用内存,之前区域全部格式化,效率较低但是能够避免产生内存碎片。
标记整理marksweeping:结合以上两者优势,在同一块内存中将有用对象复制到一块集中区域,清除此区域外的对象,效率居中且不会产生内存碎片。

垃圾回收器的种类:
cms即concurrent mark sweep 利用标记清除来实现回收,尽可能减少回收停顿时间。
g1即garbage first,jdk1.7后均默认使用g1,g1最大特点是保留了各区域的概念但是没有实际的物理隔离,实际是将整个堆内存划分为不同region,可以设置指定收集时间,g1通过记录各区域垃圾回收价值,比对收集时间,在对应时间内收集价值最大的对象(腾出更多的空间),这也是g1得名的原因
并行收集是吞吐量有先,即gc工作时间占比较小优先
并发收集是相应时间有限,不对内存进行整理,在程序执行同时进行回收,尽可能少占用cpu资源。



三、jvm参数(常用部分)


-X非标准指令,不一定向后兼容
-XX扩展指令,随时在后续版本中更改
-Xss  设置栈内存大小(默认是1M),栈内存较小可以并行更多的线程,但是得至少大于104k(不同版本及操作系统上不一样),注意此值最大为物理内存的1/3且不高于2G。
-Xmx  设置堆内存最大值,此值最大为物理内存的1/4且不高于2G。
上面说的最大内存限制是在32位环境中(默认开启client模式),64位环境中(默认开启server模式)一般不做限制,linux系统通常最大内存要比Windows稍高,最大3G左右。
-Xmn  设置堆中新生代大小(推荐,直接明确)
-XX:NewRatio 设置老生代与新生代比例(不推荐),sun官方推荐默认新生代占3/8堆内存
-XX: SurvivorRatio 设置新生代中eden和survivor区比例,默认是8即1:1:8
新生代较小,回收较快,对象更容易进入老生代,适用长期类对象较多的应用。
新生代较大,回收较慢,对象更容易在新生代被回收,适用短期类对象较多的应用。
当然决定对象是否转入下一个区域,还有专门的指令-XX:MaxTenuringThreshold=n 设置在幸存者区对象被回收n次后进入老年代,一般对于海量访问动态web,对象要么缓存起来避免直接与数据库交互,要么清除掉,不需要多次回收,所以这种情况一般设置n=0.
-XX:ParallelGCThreads=8 配置并行收集器的线程数,即同时8个线程一起进行垃圾回收。此值一般配置为与CPU数目相等。


四、jvm参数调优案例解析


大型网站服务器案例:承受海量访问的动态Web应用
服务器配置:8 CPU, 8G MEM, JDK 1.6.X
参数方案:
-server -Xmx3550m -Xms3550m -Xmn1256m -Xss128k -XX:SurvivorRatio=6 -XX:MaxPermSize=256m -XX:ParallelGCThreads=8 -XX:MaxTenuringThreshold=0 -XX:+UseConcMarkSweepGC

参数说明:服务器模式,最大及初始堆内存3550m,年轻代设置1256m(官方推荐为整个堆内存的3/8),栈内存128k尽可能小以满足海量访问多线程需求,新生代各区比例为经验值,确定方法区内存256m以避免方法区空间扩展消耗cpu资源,所以直接指定号,采用8线程,幸存者区回收次数设置为0(第三条已分析),采用cms回收器以满足快速响应的要求。


最后可以用-XX:PrintGC(根据需要加Detail)来在控制台显示GC工作过程,根据具体情况来做更改。
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值