感觉没有什么比图解更舒服的了。自己画的。。随便看看吧
整个虚拟机区域划分为了三块,我们先只研究一下Java虚拟机的数据区域怎么划分的。以及其内部的执行过程跟作用
首先我们将数据区域分为两部分,线程共享区域与非线程共享区域,你得知道并发并行的概念才能继续往下看
****************************线程共享区域*******************************
人如其名,线程共享区域就是说这个区域里边的所有数据是整个进程所共有的,包括Java堆与方法区
Java堆
解释一下Java堆,Java堆是做什么的呢?
package JavaJVM;
public class HeapDemoTest {
Person c1 = new Person(); // 1
public static void main(String[] args) {
// TODO Auto-generated method stub
Person c2; // 2
c2 = new Person(); // 3
}
}
class Person{
/**
* 空类
*/
}
举个例子讲!(往下看需要你得明白对象引用与对象的关系)
你觉得第一条语句对象引用存在哪里了?对象呢?
对象引用与对象都存放在了Java堆中为什么呢?因为他们是成员对象,记住一句话成员对象的对象引用与对象都会存在Java堆中。
第二条语句的对象引用放在哪里了,第三条语句的对象放在哪里了
我来告诉你,嘿嘿嘿 对象引用放在了Java栈中 对象放在了Java堆中。
那么Java堆里面主要存放的是什么就显而易见了,主要存放的是所有对象以及类实例的成员对象引用。这就导致了Java堆是JavaJVM数据内存中最大的一块区域,因为要存放好多好多对象呢。
Java对象放在Java堆中之后他们的状态是怎么切换的呢?
来段代码加个图呗
package JavaJVM;
public class HeapDemoTest {
Person c1 = new Person("老王"); // 1
public static void main(String[] args) {
// TODO Auto-generated method stub
Person c2; // 2
c2 = new Person("老李"); // 3
Person c3 = new Person("老刘");
}
}
class Person{
private String name;
public Person(String name){
this.name = name;
}
public String getName() {
return name;
}
public void setName(String name) {
this.name = name;
}
}
好了我们定义了三个对象,这三个对象按照规矩应该放在了Java堆中,他们出生在伊甸园(Eden),伊甸园都知道吧,一下子就记住了出生在哪吧?
如图
出生了之后呢要开始经历灾难了,在Java堆中一次灾难==一次GC,GC是什么?是Java自带的内存回收机制,程序员可以通过System.gc()建议JVM调用内存回收机制,内存回收机制比较任性,全看心情,基本不鸟程序员,所以程序员不能准确的控制内存回收的时间。
老王老刘老李三个对象经历内存回收之后呢,灾难没有杀死老王跟老李,而老刘不幸die掉了。内存回收机制发现老王跟老李他们两个比较活跃,比较乖巧就将他们归类为了幸存者,扔在了survivor区域,(这里你要知道两个幸存区域是一毛一样的,没啥区别)而老刘就凉凉啦,被内存回收机制发现偷懒不干活,直接将其杀死,也就是说清除掉了
顺便这个时候我们再次new几个对象出生在伊甸园
这个时候再次经历GC,survivor中的幸存者进行筛选,活跃的放到survivor的另一个区域,也就是说老王老李中选择活跃的放到1号区域并且将不活跃的剔除掉,伊甸园中如果有对象的话,当然也要对伊甸园进行筛选(GC是针对整个Java堆的)伊甸园筛选存活的放到一号区。
survivor 区两块区域中在GC后只会有一个区域有对象,有东西的这个区域存放的是上次GC筛选的伊甸园幸存者以及上次GC筛选的没东西的那个幸存区域的再次幸存者。。。(有点绕口,。。)
再经过好多次GC之后幸存下的对象会被认为老了,老了去哪?养老院,也就是老年代。老年代中存放的是存活时间比较长的对象
这个好多次一般是15次吧,
Java方法区中还有个持久代呢,持久代与Java堆中的年轻代老年代有关系吗?这就好比雷锋跟雷峰塔的关系,当然是没关系,都不在一个地方。。
现在基本了解了Java堆的工作了。我们看一下其他部分
方法区
方法区主要存放的是类加载时的类信息、常量数据、静态变量、以及编译器编译的相关方法的代码。
讲完了线程共享区域,我们看一下非线程共享区域
********************非线程共享区域*********************
首先非线程共享区域是什么,就是说每一个线程都有自己独立的非线程共享区域来存放数据
就感觉像每个人(线程)带着自己的行李箱(非线程共享区域)去旅游一样
Java栈
程序计数器
本地方法栈
未完待续....