Java基础之《JVM概念整理》

一、前言

我们在tomcat配置文件中会指定JVM参数:
JAVA_HOME=/opt/jdk1.8.0_152
JAVA_OPTS="-server -Xms1024m -Xmx1024m -XX:PermSize=256M -XX:MaxPermSize=512M"

说明:
-server:表示以服务模式启动,启动速度会稍微慢一点,但性能会高很多。不加这个参数,默认是以客户端模式启动
-Xms:初始堆内存大小,Server端JVM最好将-Xms和-Xmx设为相同值 
-Xmx:堆内存最大值,建议不要超过物理内存的一半
-XX:PermSize=n:设定内存永久保存区域的最小值 
-XX:MaxPermSize=n:设定内存永久保存区域的最大值

二、JVM的内存

1、那么看下JVM内存是如何分配的?
JVM的内存 = 年轻代(Young) + 年老代(Tenured) + 持久代

1)新生代(Young Generation):用于存放新创建的对象,采用复制回收方法,如果在s0和s1之间复制一定次数后,转移到年老代中。这里的垃圾回收叫做minor GC。
2)年老代(Old Generation):这些对象垃圾回收的频率较低,采用的标记整理方法,这里的垃圾回收叫做 major GC。
3)永久代(Permanent Generation):存放Java本身的一些数据,当类不再使用时,也会被回收。

2、这里可以详细的说一下新生代复制回收的算法流程:
在新生代中,分为三个区:Eden, from survivor, to survior。
1)当触发minor GC时,会先把Eden中存活的对象复制到to Survivor中;
2)然后再看from survivor,如果次数达到年老代的标准,就复制到年老代中;如果没有达到则复制到to survivor中,如果to survivor满了,则复制到年老代中。
3)然后调换from survivor 和 to survivor的名字,保证每次to survivor都是空的等待对象复制到那里的。
PS:新生代到年老代有一个过度过程

三、堆(Heap)和非堆(Non-heap)内存

按照官方的说法:“Java 虚拟机具有一个堆,堆是运行时数据区域,所有类实例和数组的内存均从此处分配。堆是在 Java 虚拟机启动时创建的。”“在JVM中堆之外的内存称为非堆内存(Non-heap memory)”。
可以看出JVM主要管理两种类型的内存:堆和非堆。简单来说堆就是Java代码可及的内存,是留给开发人员使用的;非堆就是JVM留给自己用的。

四、JDK8新增

1、从JDK8开始,永久代(PermGen)的概念被废弃掉了,取而代之的是一个称为Metaspace的存储空间。
区别:
PermSize有默认值,可以设置初始大小和最大大小
Metaspace使用的是本地内存,可以设置初始大小和最大大小
Metaspace不进行任何设置的情况下,最大限制就是系统内存大小,内存足够的情况下,不会出现OOM,但是如果占用太多会不会被系统进程kill掉?

参考资料:
https://www.cnblogs.com/xing901022/p/7725961.html
https://blog.csdn.net/KilluaZoldyck/article/details/75094855
https://www.cnblogs.com/tomcatandjerry/p/4218589.html

猜你喜欢

转载自blog.csdn.net/csj50/article/details/80135076