您的位置:首页 > 编程语言 > Java开发

java的内存区域的模型

2016-03-11 00:00 267 查看


这篇主要是对java 中内存模型的初步认识,作为了解类初始化过程,垃圾回收算法的基础(上面的图是导来的)

程序计数器(线程私有的)

java虚拟机的多线程是通过线程轮流切换来实现的,为了使线程在切换后还能恢复到正确的执行位置,每一个线程都需要一个独立的程序计数器。它用来记录下一个要运行的指令

2.Java虚拟机栈

虚拟机的栈也是线程私有的,虚拟机栈描述的是Java方法执行的内存模型:每个方法在执行时都会创建一个栈帧用来存储定义在方法内部的局部变量,操作数栈、动态链接、方法出口、返回类型等信息。方法从调用到执行,相当于栈帧在虚拟机栈中的入栈和出栈的过程。



其中局部变量表,存储的是java8个基本类型的数据,对象的引用(reference)

3.本地方法栈

JNI(Java native interface)java的本地方法调用接口,主要是为java调用windows系统的c\c++的方法提供服务。在不同的虚拟集中,把java虚拟机栈和本地方法栈和二位一

4.Java 堆

java虚拟机中管理最大的一块空间,几乎所有的对象实例和数组都分配在java的堆中,供其它线程使用,所以java堆是线程共享的。Java堆还是垃圾收集器的主要管理的区域,成为GC堆(Garbage Collection Heap),由于现在的收集器都采用分代收集的算法,所以堆大致可以分为新生代,老年代,永久代,其中新生代是垃圾收集器的主要收集的区域,基本上清理对象达到70%以上,但也不失绝对的。

新生代的比例大致又分为Eden空间,From Survivor空间,To Survivor 空间,一般的分配比例为8:1:1,所以新生代每次可以分配的空间是新生代空间的90%,在对90%的空间进行第一次GC时,对于还存活的对象实例和数组,虚拟机会把这些对象实例复值到To survivor 的空间里去,当然,当清理后剩余大于10%时则需要老年代来帮忙。

这里补充下对各种GC的区别,Minor GC、Major GC和Full GC
(1)Minor GC 主要是对新生代中的 Eden和Survivor区域进行内存回收
(2)Major GC 是清理永久代的空间
(3)Full GC是清理整个堆空间,包括了新生代,老年代和永久代
5.方法区
方法区也是线程共享的,用来存储已经被加载的类的结构信息,例如常量,静态变量,方法数据,构造函数和普通方法的字节码内容。(自己的理解,不知道对不对)方法区是加载属于类的一些信息(常量,静态变量、方法等),而在堆中已经实例的对象是共享这些信息的,这些类的实例对象中持有的是对类信息的引用。我们可以写代码来验证一下。

下面 类A中有一个静态变量和一个普通的变量,2个A的实例化对象,假设2个实例化对象是持有对类A的静态变量的引用,那么当实例对象a修改静态变量时,a1打印出来的也是一样的值
public class jvmYongOld {
private static final int _1MB=1024*1024;
public static void main(String[] args) {
A a=new A();
A a1=new A();
a.print();
a1.print();
a.a=4;
a.print();
a1.print();
a.b=9;
a.printb();
a1.printb();
}
}

class A{
static int a=3;
int b=3;
static void print(){
System.out.println("a="+a);
}
void printb(){
System.out.println("b="+b);
}
}




根据打印结果,上面的假设都是对的,也就是说,静态变量,常量等信息都是属于类的,类的实例对象只是持有对其的引用。

最后上一幅《深入理解java虚拟机中》的图片,可以形象的表述下栈,堆,方法区的关系

内容来自用户分享和网络整理,不保证内容的准确性,如有侵权内容,可联系管理员处理 点击这里给我发消息
标签: