Jvm的简单认识(适合入门者和初学者)

Tip: jvm是一个庞大的知识体系,其中与开发比较有关联的是内存部分,所以本篇着重介绍内存部分,实践部分极少

所以本篇适合初学者或者入门者,用于理解各种知识点和面试时候可以叨一叨

一.结构

1.方法区(永久区):

方法区和堆类似,是各个线程共享的内存区域,它用于存储类信息,常量,静态变量,即时编译器编译后的代码(项目发布jsp等会被解析成java代码,大量内容会进进出出,就有可能出现方法区溢出的异常)等数据。分析下Java虚拟机规范,之所以把方法区描述为堆的一个逻辑部分,应该觉得她们都是存储数据的角度出发的。一个存储对象数据(堆),一个存储静态信息(方法区)。

2.堆 (线程共享)

对于大多数应用来说,堆是Java虚拟机管理的内存的最大一块,这块区域随着虚拟机的启动而创建。我们创建的对象和数组就是存放在堆里面。它是一块共享的区域,操作共享区域的成员就有了锁和同步(线程的安全问题)。

堆是垃圾回收器管理(GC)的主要区域。新生代、老生代、永久代的概念就是在堆里面,下文会详细介绍这些

堆内存可以处于物理上不连续的内存空间中,只要逻辑上是连续的即可。

3.栈(线程私有)

栈是线程私有的,它的生命周期与线程相同。栈描述的是Java方法执行时的内存模型,每个方法执行时都会创建一个栈帧(Stack Frame)用来存储局部变量表、操作数栈、动态链接、方法出口等信息。每个线程在执行一个方法时,都意味着有一个栈帧在当前线程对应的栈帧中入栈和出栈。

4.程序计数器

记录程序执行到哪一行

5.本地方法栈

jvm是Java执行的平台,但是程序也会调用一些本地操作系统的方法(在windows就是windows中的本地方法,linux则是linux的本地方法),例如一些IO操作等,这些方法就在本地方法栈中。

 

详细介绍堆内存

1.新生代:

这里也划分三个区域

Eden:对象进入的时候在这里生活,非常欢乐

from:这时候GC垃圾回收来了,他认为不需要的就进行移动回收

to:复制算法使用的空间(下文详细介绍)

这里from:to:Eden大小默认1:1:8 可以自行进行配置

2.老年代

经过N次(默认15)的垃圾回收还留存的,会送往老年代

3.永久区

这里也有垃圾回收机制,本文不多做介绍。有兴趣自行搜索资料

二.垃圾回收(GC)

我们java程序员写程序是不用关注内存(例如C语言需要,这是一件十分棘手的事情),这得益于垃圾回收机制。

1.如何判定是垃圾(这里直说大致原理)

依靠根节点搜索:从程序最根本的那个类开始,看他能够到达哪一些对象,这些可到达的对象就会认为是有用的对象,到达不了的认为是垃圾。(更详细的请自行搜索资料)

2.回收算法(如何回收)

Tip:内存空间里面就是一个个内存地址,这里把内存地址显示为一个个小方格,方便理解

第一种算法 : 标记清除法

1>.标记出所有需要回收的对象,在标记完成后统一回收所有被标记的对象

2>.在标记完成后统一回收所有被标记的对象

缺点:一个是效率问题,标记和清除两个过程的效率都不高;

另一个是空间问题,不难想象抽走黑色部分,空出来的部分是不连续的,这时候大对象的存储很可能无法找到足够的连续内存。

 

第二种算法: 标记整理法

把有用的找出来,全部往一个方向移动并且覆盖掉没用的,然后剩下的位置全部清理掉。

缺点:效率慢。并且移动他的内存空间会对用户产生速度的影响。

第三种算法:复制算法

1>将可用内存按容量划分为大小相等的两块,每次只使用其中的一块。

1>垃圾回收时 把有用的拷贝到另一半空的空间,然后清理全部,再把有用的拷贝回来(图中没显示拷贝回来的)。

优点:往内存空白处复制操作效率高效,实现简单。并且时常内存中垃圾占大多数,存活的是少数,也就是不一定要留下一半空间,可以选择留下更少的空间。

缺点:复制收集算法在对象存活率较高时就要进行较多的复制操作,效率将会变低

Tip:

在新生代中,每次垃圾收集时都发现有大批对象死去,只有少量存活,那就选用复制算法,只需要付出少量存活对象的复制成本就可以完成收集。

老年代中因为对象存活率高、没有额外空间对它进行分配担保,就经常使用“标记—清理”或者“标记—整理”算法来进行回收。

 

3.垃圾回收具体的实现(垃圾回收器)

-----这里只做最简单介绍,它们的实现是非常复杂的,有兴趣可以自行去了解

垃圾回收器有以下几种

1.Serial收集器:

1>、是一个单线程(它工作时,用户线程不工作)的收集器,用户那边称作“Stop The World”

2>、对于运行在Client模式下的虚拟机来说是一个很好的选择

3>、简单而高效

2.Serial Old收集器:

1>、Serial收集器的老年代版本,它同样是一个单线程收集器,使用“标记-整理”算法。

2>、主要意义也是在于给Client模式下的虚拟机使用。

3>、如果在Server模式下,那么它主要还有两大用途:

一种用途是在JDK 1.5以及之前的版本中与Parallel Scavenge收集器搭配使用[1],

另一种用途就是作为CMS收集器的后备预案,在并发收集发生Concurrent Mode Failure时使用。

 

3.CMS收集器一款优秀的收集器(服务端默认)

1>、以获取最短回收停顿时间为目标的收集器。

2>、重视服务的响应速度,希望系统停顿时间最短。

3>、基于“标记—清除”算法实现的。

4>、CMS收集器的内存回收过程是与用户线程一起并发执行的。

5>、优点:并发收集、低停顿

 

4.G1(Garbage-First)收集器

1>、当今收集器技术发展的最前沿成果之一

2>、G1是一款面向服务端应用的垃圾收集器。

3>、优点:

        并行与并发:充分利用多CPU、多核环境下的硬件优势

        分代收集:不需要其他收集器配合就能独立管理整个GC堆

        空间整合:“标记—整理”算法实现的收集器,局部上基于“复制”算法不会产生内存空间碎片            

        可预测的停顿:能让使用者明确指定在一个长度为M毫秒的时间片段内,消耗在垃圾收集上的时间不得超过N毫秒

Tip:还有另外多种收集器这里不过多介绍。

 

 

垃圾收集器参数总结

收集器设置:

-XX:+UseSerialGC:年轻串行(Serial),老年串行(Serial Old)

-XX:+UseParNewGC:年轻并行(ParNew),老年串行(Serial Old)

-XX:+UseConcMarkSweepGC:年轻并行(ParNew),老年串行(CMS),备份(Serial Old)

-XX:+UseParallelGC:年轻并行吞吐(Parallel Scavenge),老年串行(Serial Old)

-XX:+UseParalledlOldGC:年轻并行吞吐(Parallel Scavenge),老年并行吞吐(Parallel Old)

收集器参数:

 

-XX:ParallelGCThreads=n:设置并行收集器收集时使用的CPU数。并行收集线程数。

-XX:MaxGCPauseMillis=n:设置并行收集最大暂停时间

-XX:GCTimeRatio=n:设置垃圾回收时间占程序运行时间的百分比。公式为1/(1+n)

-XX:+CMSIncrementalMode:设置为增量模式。适用于单CPU情况。

-XX:ParallelGCThreads=n:设置并发收集器年轻代收集方式为并行收集时,使用的CPU数。并行收集线程数。

 

垃圾回收统计信息

-XX:+PrintGC

-XX:+PrintGCDetails

-XX:+PrintGCTimeStamps

-Xloggc:filename

 

 

三.Jvm参数列表

java -Xmx3550m -Xms3550m -Xmn2g -Xss128k -XX:NewRatio=4 -XX:SurvivorRatio=4 -XX:MaxPermSize=16m  -XX:MaxTenuringThreshold=0

-Xmx3550m:最大堆内存为3550M。

-Xms3550m:初始堆内存为3550m。

此值可以设置与-Xmx相同,以避免每次垃圾回收完成后JVM重新分配内存。

-Xmn2g:设置年轻代大小为2G。

整个堆大小=年轻代大小 + 年老代大小 + 持久代大小。持久代一般固定大小为64m,所以增大年轻代后,将会减小年老代大小。此值对系统性能影响较大,Sun官方推荐配置为整个堆的3/8。

-Xss128k:设置每个线程的堆栈大小。

JDK5.0以后每个线程堆栈大小为1M,在相同物理内存下,减小这个值能生成更多的线程。但是操作系统对一个进程内的线程数还是有限制的,不能无限生成,经验值在 3000~5000左右。

-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=15:设置垃圾最大年龄。

如果设置为0的话,则年轻代对象不经过Survivor区,直 接进入年老代。对于年老代比较多的应用,可以提高效率。如果将此值设置为一个较大值,则年轻代对象会在Survivor区进行多次复制,这样可以增加对象 再年轻代的存活时间,增加在年轻代即被回收的概论。

 

 

 

  • 6
    点赞
  • 36
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值