图解Java虚拟机数据区域

感觉没有什么比图解更舒服的了。自己画的。。随便看看吧

整个虚拟机区域划分为了三块,我们先只研究一下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方法区里面有个持久代 用于存放静态文件,如今Java类、方法等。持久代对垃圾回收没有显著影响,但是有些应用可能动态生成或者调用一些class,例如Hibernate 等。。

讲完了线程共享区域,我们看一下非线程共享区域

********************非线程共享区域*********************

首先非线程共享区域是什么,就是说每一个线程都有自己独立的非线程共享区域来存放数据

就感觉像每个人(线程)带着自己的行李箱(非线程共享区域)去旅游一样

Java栈

程序计数器

本地方法栈

未完待续....





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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值