有什么错误欢迎指正
这个是jvm的基本结构:
一、PC寄存器
每个线程拥有一个PC寄存器
在线程创建时 创建
指向下一条指令的地址
二、方法区
保存装载的类信息(类加载的时候生成的类的信息,具体可以看反射原理)
· 类型的常量池
· 字段,方法信息
· 方法字节码
通常和永久区(Perm)关联在一起
三、java堆
和程序开发密切相关的
应用系统对象都保存在Java堆中
所有线程共享Java堆
对GC来说,堆是分代的(新生代,老生区)
GC的主要工作区间(GC的主要工作空间是堆和永久区)
GC有助于提高从堆上创建对象的速度:
因为在某些java虚拟机中,堆的实现更像一个传送带,每分配一个对象,它就向前 移动一格,这就意味着给对象分配空间上是很快的,java的“堆指针”只是简单的移动到尚未分配的区域。但是java中堆没有完全像传送带那样工作,因为如果那样的话肯定会导致频繁的内存页面调度将其移进移出,开销很大。其实最重要的还是垃圾回收器的介入,当它工作时,将一面回收空间,一面是使堆中的对象紧凑排列(这里面涉及到GC的原理和算法,在下个博客讲),这样“堆指针”就很容易移动到靠近传送带的开始处。所以创建速度比较快。
四、java栈
java栈是线程私有的,主要包含参数和局部变量
栈由一系列帧组成(因此Java栈也叫做帧栈)
帧保存一个方法的局部变量、操作数栈、常量池指针
每一次方法调用创建一个帧,并压栈
参数传递是使用操作数栈的
如下面的参数 a,b 计算出局部变量c,用的是操作数栈的方式,也就是压栈和弹出计算。
public static int add(int a,int b){
int c=0;
c=a+b;
return c;
}
Java栈的栈上分配
小对象(一般几十个bytes),在没有逃逸的情况下,可以直接分配在栈上
直接分配在栈上,可以自动回收,减轻GC压力
大对象或者逃逸对象无法栈上分配
五、栈、堆、方法区交互
public class AppMain
//运行时, jvm 把appmain的信息都放入方法区
{
public static void main(String[] args)
//main 方法本身放入方法区。
{
Sample test1 = new Sample( " 测试1 " );
//test1是引用,所以放到栈区里, Sample是自定义对象应该放到堆里面
Sample test2 = new Sample( " 测试2 " );
test1.printName();
test2.printName(); }