JVM内存 新生代 老年代 垃圾回收

JVM基本结构

 

 

 

 

句柄池

 

JDK8中把存放元数据中的永久内存从堆内存中移到了本地内存(native memory)中,这样永久内存就不再占用堆内存,它可以通过自动增长来避免JDK7以及前期版本中常见的永久内存错误(java.lang.OutOfMemoryError: PermGen)。

 

①类加载子系统:负责从文件系统或网络中加载class信息,存放在方法区中

方法区:存放类信息静态信息常量信息、常量池信息、字符串常量和数字常量等)所有线程共享,可以理解为永久区(常量池是其中的一部分)   

Java堆:Java虚拟机在启动的时候创建Java堆,它是Java程序最主要的内存工作区域,所有的对象实例放在Java堆中堆空间是所有线程共享的,一个JVM一个堆

④直接内存:Java的NIO允许Java程序直接使用内存,从而提高性能,直接内存速读高于Java堆,读写频繁时可以考虑使用        

Java栈:每个虚拟机线程都有私有的栈,一个线程的Java栈,在线程创建的时候被创建,Java栈中保存着局部变量、方法参数、Java方法的调用和返回值等,一个线程一个栈     

⑥本地方法栈:线程私有,与Java栈很相似,最大的不同在于,本地方法栈用于本地方法调用,Java虚拟机栈允许Java直接调用本地方法(通常用C编写)

垃圾回收系统:是Java的核心,也是必不可少的,Java有一套自己的垃圾回收机制 

⑧PC寄存器:是每个线程私有的空间,Java虚拟机会为每个线程创建PC寄存器,存放当前执行环境指针,程序计数器,操作栈指针等 

⑨执行引擎:核心组件,他负责执行虚拟机的字节码

堆、栈、方法区关系

堆:解决的是数据存储问题,怎么放,放在哪

栈:解决的是程序运行问题,程序如何执行,或者说如何处理数据

方法区:辅助堆栈的永久区,解决堆栈信息的产生,是先决条件

关系:一个User类;

类信息和静态信息存放在方法区中;

而实例引用和局部变量存放在栈中;

而实例对象放在堆中。

Java堆

线程间共享,Java堆是和Java应用程序关系最密切的内存空间,几乎所有的对象都放在其中,并且Java堆是自动化管理,通过垃圾回收机制,垃圾对象自动清理

Java堆结构图:

根据垃圾回收机制不同,Java堆有不同的结构,最常见的是将Java堆分为新生代和老年代

eden区:存放的是刚实例化出来的数据,当对象经历过一次GC的时候,就会将对象放在S0或者S1区

S0和S1:也称为form和to区,这两个区域大小相等,并可以互换角色,是由于复制算法

复制算法:其思想就是将内存空间分为两块,每次只是用其中一块(S0或者S1),在垃圾回收时,将正在使用的对象复制到S1,然后将S0的对象全部回收,反复去交换这两个内存角色,完成垃圾回收

tenured区:老年区,当对象每经历过一次GC,就会加一,到达一定阀值后(默认15),就会进入老年区

新生代和老年代都会经历GC回收,只是新生代频繁GC,而老年代不频繁GC

新生代与老年代的比例:1:2 0r  1:3

Java栈

Java栈是线程私有的内存空间(线程间独立),由三个部分组成:局部变量表、操作数栈、帧数据区

局部变量表:用于报错函数的参数及局部变量

操作数栈:主要保存计算过程的中间结果,同时作为计算过程中变量临时的存储空间

帧数据区:保存至访问常量池的指针,还有当函数出现异常时,虚拟机需要的异常处理表

Java方法区

线程间共享,保存类信息,方法区大小决定了系统可以保存多少类,如果系统定义太多的类,会导致虚拟机抛出内存溢出异常,方法区可以理解为永久区

堆参数配置

 

垃圾回收及其算法

垃圾回收针对的是堆区

垃圾回收有很多算法:引用计数法、复制算法、标记压缩法,分代、分区思想

引用计数法:比较古老的垃圾收集算法,对象被引用+1,失去引用-1,弊端:无法处理循环引用

标记清除法:就是分为标记和清楚两个阶段,进行处理内存中的对象,弊端:空间碎片问题

复制算法(新生代):将内存分为两块,每次只是用其中一块,在垃圾回收时,将正在使用的对象复制到B内存区中,然后将A区的所有对象清楚,反复交换两个内存的角色,完成垃圾回收(Java中新生代的from和to空间就是使用的复制算法)

标记压缩法(老年代):是在标记清楚法基础上做了优化,把存活的对象压缩到内存的一段,而后进行垃圾清理

为什么新生代和老年代使用不同的算法?因为新生代GC回收的次数频繁,而老年代不频繁(因为老年代的对象比较稳定,所以需要回收的对象少,如果使用复制算法就浪费性能了)

垃圾回收时会暂时停顿

对象如何进入老年代

对象创建流程图

http://www.cnblogs.com/chenyangyao/p/5296807.html

JVM调优常用参数

  • 堆设置

-Xms64m:初始化内存

-Xmx64m:最大内存

-XX:NewSize=n:设置年轻代大小

-XX:NewRatio=n:设置年轻代和年老代的比值,1:2和1:3比较合理

-XX:MaxPermSize=n:设置持久代大小

-XX:MaxTenuringThreshold=15:新生代转换为老年代的阀值,默认15

-XX:PretenureSizeThreshold 指定对象超过一定的大小,就会直接晋级老年代,但是要注意TLAB区域优先分配空间,单位k

  • 收集器设置

-XX:+UseSerialGC:设置串行收集器

-XX:+UseParallelGC:设置并行收集器,Parallel

-XX:+UseParalledlOldGC:设置并行年老代收集器,Parallel

-XX:+UseConcMarkSweepGC:设置并发收集器,CMS

-XX:ConcGCThreads:设置并发线程数量,CMS

-XX:+UseG1GC:使用G1回收器

  • 并行收集器设置

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

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

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

-XX:UseAdaptiveSizePolicy 自动调整MaxGCPauseMillis、GCTimeRatio等

-XX:+UseParNewGC新生代回收器=ParNew OR  ParallelGC

  • 并发收集器设置

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

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

  • 垃圾回收统计信息

-XX:+PrintGC

-XX:+PrintGCDetails

-XX:+PrintGCTimeStamps

  • 查看JVM默认参数等信息

java  -XX:+PrintFlagsInitial

http://blog.csdn.net/java2000_wl/article/details/8042010

注:一个Tomcat占用一个JVM进程;当应用没有人用时,和有人用时,系统的内存是不一样的,也就是说JVM会动态的向系统申请内存

JVM博客:

http://www.cnblogs.com/redcreen/archive/2011/05/04/2037057.html

垃圾回收器

根据作用于不同的堆空间,分为新生代回收器和老年代收集器

串行垃圾收集器:单线程进行垃圾回收

并行垃圾收集器:多个线程进行垃圾回收

CMS回收器:并发标记清楚,标记清除法,关注系统停顿时间

ParalledlOldGC: 关注系统吞吐量

Java8默认:G1收集器,以前是CMS收集器

压测服务器吞吐量

 

 

 

 

 

Major GC和Full GC的区别是什么?

https://www.zhihu.com/question/41922036

 

 

 

JVM性能监控与故障处理工具

  • JPS

JVM 进程状况工具

LVMID(vmid,虚拟机进程id)==PID(OS进程id)

jps -l :输出本机JVM的vmid(虚拟机进程id)和路径

jps -v:输出本机JVM的vmid(虚拟机进程id)和启动JVM时的参数

  • jstat

JVM统计信息监视工具

jstat -gcutil vmid

E:Eden新生代使用率%

S0,S1:Survivor区使用率%

O:老年代使用率%

M:方法区使用率%

YGC,YGCT:YongGC,程序运行以来共发生MMinorGC 74次 耗时0.381秒

FGC,FGCT:FullGC,程序运行以来共发生FullGC 1次 耗时0.049秒

  • jinfo

Java配置信息工具

  • jmap

Java内存映像工具

jmap -heap vmid:显示Java堆详情信息

  • JConsole

Java可视化监控

进入本地JDK目录

/Library/Java/JavaVirtualMachines/jdk1.8.0_121.jdk/Contents/Home/bin

输入jconsole,然后在使用远程连接

  • jvisualvm

强大的可视化 多合一故障处理工具

  • jstack

查看Java栈和本地栈信息,也可以看线程的运行情况

jstack [ option ] pid 

jstack和thread dump的结果相同

http://blog.csdn.net/xiao_287130/article/details/53607428

  • 2
    点赞
  • 1
    收藏
    觉得还不错? 一键收藏
  • 1
    评论
评论 1
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值