我们接着上一篇文章讲解:
堆、栈、永久区比较
Heap(堆内存):
在Java中,创建的所有引用对象类型,都在堆内存中。堆内存中的数据由GC对其进行管理的。其实堆内存也是GC主要管理的地方。
如:释放不再被程序引用的对象所占用的内存
Stack(栈内存)
栈内存与堆内存是相对的。栈内存存放的是基础数据类型。如:int、long等。是由程序的执行顺序控制变量的进出栈顺序,这里的数据不受GC管控的。
Perm(永久区)
永久区是用于存储类的元数据。如:类的定义、方法定义(application metadata),用来描述类及方法的元数信息。
需要注意的是:永久区不是堆的一部分。
永久区的生命周期与JVM是绑定的;
堆内存的生命周期与程序绑定的。
内存管理优化参数:
-Xms
设置JVM启动时的堆内存(Heap)的大小
-Xmx For setting the maximum heap size.
设置堆内存(Heap)的最大值
-Xmn
设置 Young Gen 内存区的大小
-XX:PermGen
设置 Perm Gen 内存的初始大小
-XX:MaxPermGen
设置 Perm Gen 内存的最大值
-XX:SurvivorRatio
设置 Eden Gen 与 S0 Gen,S1 Gen 内存的大小比。默认值:8
例如:
Young Gen 大小为 10M,
-XX:SurvivorRatio=2
则:
Eden Gen 的大小为 5,
S0 和 S1 的大小分别为 2.5
-XX:NewRatio
设置 Old Gen / Young Gen 的值。默认:2
大部分情况下,默认值不用调。
JDK1.8堆内存模型
从上图中我们可以看出,在JDK1.8的内存模型中是由2部分组成的:年轻代和年老代
年轻代:Eden+2*svrvivor
年老代:OldGen
1.8与1.7堆内存模型区别:
在1.8中最大的变化就是Perm区(年老区),用metaspace(元数据空)进行了替换。
这里需要特别强调的是:元数据区(metaspace)所占用的内存空间并非虚拟机内部的,而是直接在本地的内存空间中。这也是1.8与1.7永久代最大的区别所在。
在1.8之后为什么要废弃掉1,7中永久区呢?
官方给出的答案:
在实际使用中,永久区内存经常会出现不够用的情况或是发生内存泄漏,也就是抛出java.lang.OutOfMemoryError:PermGen的错误。基于这个原因,才改用使用本地内存空间。
本文是《JVM学习系列》中的第三篇文章。如果想系统的学习,建议从本教程第一篇开始看。
下节预告: