java畅谈2

今天主要看了JVM书中的第二章java内存区域和编程思想一书中的内部类。接下来谈谈自己的理解。


   先说说JVM吧。话说是一个运行平台。在编译器编译产生的class文件会在JVM中被加载和解释执行的。JVM有许多种早期的是SUN classic VM之后出现hotspot和BEA公司的JRockit、还有IBM的J9。他们都是JVM,但是我们现在接触的是Hotspot,他是SUN公司的,不过现在是Oracle公司的了。
  1、 接下来讲讲java的内存动态分配和垃圾回收机制。这两个特点是java区别c++的最大的原因。java的内存 区域分成了几部分的数据区:方法区、堆、虚拟机栈、本地方法栈、程序计数器。
程序计数器:首先是线程隔离的。他可以看作是线程所执行的字节码行号的指示器。字节码解释器会根据计数器来选取将要执行的语句。注意他是线程隔离的,每条线程都有自己的程序计数器。各个线程的计数器是互不影响的。这个区域是唯一没有任何规定会出现OutMemoryError的区域。


虚拟机栈:也是线程隔离的。就是我们平常经常说的栈。主要用来存储局部变量表、操作数栈、动态链接、方法出口等。局部变量表存放了编译期出现的基本数据类型、对象引用(在hotspot中对象的引用就是堆中对象实例的绝对地址的值)。


本地方法栈:是线程隔离的,主要是为了使用本地方法服务的。在hotspot中将本地方法栈和虚拟机栈是合二为一的。


堆:首先是线程共享的。主要就是存放对象实例的。所有的对象实例和数组都在堆上分配的。同时堆也是垃圾收集机制管理的主要区域。


方法区:是线程共享的。在hotspot虚拟机中方法区也属于堆的一部分。主要用于存储已被虚拟机加载的类信息、常量、静态变量即时编译器编译后的代码。
运行常量池:是方法区的一部分。用于存放编译期生成的各种字面量和符号的引用。
    2、Hotspot虚拟机对象
当虚拟机遇到new指令的时候,首先检查能不能在常量池中找到该类的符号引用。顺便检查是否已被加载、解析和初始化过。如果没有就进行相应的类加载。接下来虚拟机为新对象分配内存。一般会由两种分配方式:指针碰撞和空闲列表。通常采用的是空闲列表法。
对象在内存中的布局分为3块区域:对象头、实例数据和对齐填充。
对象头:包含两部分。一是存储对象自身运行时的数据。另一部分是类型指针即对象指向它的类元数据的指针。虚拟机通过这个指针来确定这个对象是那个类的实例。
实例数据:代码中所定义的各种类型的字段。无论是从父类继承的,还是子类定义的都需要记录下来。
对齐填充:仅仅是起占位符的作用。由于hotspot VM要求对象的起始地址必须是8字节的整数倍。因此当对象实例数据没有对齐时就需要通过对齐填充来补全。


  3、这一点很重要是java中不存在引用传递,只有值传递。在java程序中通过栈上的reference数据来操作堆上的具体对象。reference是一个指向对象的引用。hotspot在对象的访问方式上使用的是直接地址。即reference数据存储的就是堆中对象的绝对地址的值。
目前主流的访问方式是:直接地址法和句柄访问法。hotspot采用的是直接地址法。
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值