1、首先运行程序,Demo1_car.java就会变为Demo1_car.class,将Demo1_car.class加入方法区,检查是否字节码文件常量池中是否有常量值,如果有,那么就加入运行时常量池
2、遇到main方法,创建一个栈帧,入虚拟机栈,然后开始运行main方法中的程序
3、Car c1 = new Car(); 第一次遇到Car这个类,所以将Car.java编译为Car.class文件,然后加入方法区,跟第一步一样。然后new Car()。就在堆中创建一块区域,用于存放创建出来的实例对象,地址为0X001.其中有两个属性值 color和num。默认值是null 和 0
4、然后通过c1这个引用变量去设置color和num的值,
5、调用run方法,然后会创建一个栈帧,用来装run方法中的局部变量的,入虚拟机栈,run方法中就打印了一句话,结束之后,该栈帧出虚拟机栈。又只剩下main方法这个栈帧了
6、接着又创建了一个Car对象,所以又在堆中开辟了一块内存,之后就是跟之前的步骤一样了。
1)jdk1.8之前模型
1、什么是 Perm Gen?
Perm Gen : Permanent Generation
Perm Gen 区是一个特殊的JVM内存区,因为它用来存储用来描述 Class 的
元数据(Class 可以不属于Java语言的一部分,也可以属于),诸如:描述类及其方法。
在大的应用中该区一会儿就满了,并抛出错误:java.lang.OutOfMemoryError: PermGen
然而无论你怎么设置 -Xmx 也不管用。
因为设置其大小的参数不是 -Xmx,而是 -XX:PermGen, -XX:MaxPermGen (不同Java版本略有变化)
2、Heap VS. Stack VS. Perm
Heap(堆内存):
使用Java语言创建的所有的引用对象类型,都在此存储。并由 GC (Garbage Collection)对其进行管理,
诸如:释放不再被程序引用的对象所占据的内存。
Stack(栈内存):
与 Heap 相对的是,Stack 存放基础数据类型。诸如:int, char 等。
由程序的执行顺序控制变量的进出栈顺序,而不是由 GC 控制栈内存的管理。
Perm(持久内存):
用于存储类的元数据。诸如:类的定义,方法的定义等。
Perm 的生命周期与 JVM 绑定,而 Heap 的生命周期与程序绑定。
二、堆内存(Heap) 与 Garbage Collection
理解 GC (Garbage Collection),需要理解 Heap 。
JVM 的 Heap 堆内存在物理上被划分为两部分:Young Gen, Old Gen
1、 JVM 内存管理之:Young Gen
所有新创建的 Object 首先被放在 Young Generation 内存区。
如果 Young Generation 内存区满了,则执行 Garbage Collection 。这种 GC 称为 Minor GC。
Young Generation 区又分为三部分: Eden Memory,Survivor0 Memory (S0),Survivor1 Memory(S1).
Young Generation 内存区要点:
1、绝大多数新建的 Object 被放在 Eden Memory
2、如果 Eden Memory 内存满了,则进行 GC 操作。
同时把未被 GC 的 Object 移动到 S0 或 S1 中。
此时 Minor GC 也会检查和移动 S0 和 S1 中的对象。
最后使 S0,S1 其中一个置为空。
3、多次 GC 后仍然未被 GC 的 Object 将被移动到 Old Gen 内存区中。
通常 Object 会被 GC 设定一个轮询的阀值。
2、 JVM 内存管理之:Old Gen
Old Gen 内存区存放了经过多次 Minor GC 后仍然不能被 GC 的 Object。
与 Young Gen 相同,当 Old Gen 区满了之后将执行 GC 操作,该操作称为:Major GC。
耗用的时间也相对较长。
stop-the-world 事件
Young Gen 和 Old Gen 都可以主动触发 stop-the-world 事件,挂起所有任务,执行 GC 操作。
被挂起的任务只有在 GC 执行完毕后,才会恢复执行。
多数情况下, GC 性能调优(GC tuning)就是指降低 stop-the-world 时 GC 执行的时间。
三、Perm Gen
JVM 在 Permanent Generation 或 Perm Gen 内存区中存放应用程序的元数据
(application metadata),用来描述类及其方法的原始信息。
注意:Perm Gen 不是 Heap 的一部分。
Perm Gen 被 JVM 使用于应用程序运行期间(runtime),基于应用所使用到的类。
Perm Gen 中同时包括 Java SE 包中的类。
Perm Gen 只有在执行 Full GC 时才会被 GC。
JDK8中JVM堆内存结构就变成了如下:
这样永久内存就不再占用堆内存,它可以通过自动增长来避免JDK7以及前期版本中
常见的永久内存错误(java.lang.OutOfMemoryError: PermGen),也许这个就是你的
JDK升级到JDK8的理由之一吧。当然JDK8也提供了一个新的设置Matespace内存
大小的参数,通过这个参数可以设置Matespace内存大小,这样我们可以根据自己
项目的实际情况,避免过度浪费本地内存,达到有效利用。
通常jdk会带有两个分析jdk内存情况的软件 如:jvisualvm.exe jconsole.exe
个人觉得jvisualvm.exe 这个比较好用(安装查看内存模型插件比较好转~),当然看大家个人喜好了,本文就针对jvisualvm 使用 以及插件安装说了,有人想了解jconsole 可以打开试一下!
a 运行软件
b 查看自己的应用内存使用情况
注:这里注意一下 ,菜单功能 visual GC 这个插件不是自带需要自己手动添加,就可以查看堆内存使用情况