java内存相关知识

来源:互联网 发布:数据库测试题 编辑:程序博客网 时间:2024/05/22 08:27

java虚拟机会将其管理的内存划分为不同的数据区域

程序计数器:该程序计数器与cpu中的程序计数不同,java虚拟机在自己的内存中设立一片区域来模拟cpu程序计数器。虚拟机规定每一个线程都有自己的程序计数器。其作用是用来指向正在执行的字节码地址。
:jvm启动就创建了堆内存区,堆是线程共享的运行时内存区域,也是供所有类实例和数组对象分配内存的区域。它存储了被内存管理器监管的对象。这些对象不用显式的被销毁
方法区:也是各个线程共享的区域,它用于存储已经被虚拟机加载过的类信息,常量,静态变量,及时编译期编译后的代码(类方法)等数据。这里要提到运行时常量池,它是方法区的一部分,用于存放编译期生成的各种字面量和符号引用(其实就是八大基本类型的包装类型和String类型数据)

new对象

当虚拟机遇到一条new指令的时候,首先会去检查所new的类是否已经被加载,在哪里检查?当然在方法区,方法区存放了加载过的类信息。如果没有加载,那么先执行类的加载。 通过类加载检查后,虚拟机开始为新生对象分配内存,对象所需要的内存大小在类加载完成后已经可以确定,这时候只要在堆中分配空间即可。分配内存有两种方式,第一种,我们假设内存绝对规整,那么只要在用过的内存和没用过的内存间放置一个指针即可,每次分配空间的时候只要把指针向空闲空间移动相应距离即可。第二种,我们假设空闲内存和非空闲内存夹杂在一起,实际上就是这种情况,那么就需要一个列表,去记录堆内存的使用情况,操作系统对内存的管理就是这样的。 那么,我们还要考虑一个问题,即在多线程的情况下,只有一个指针怎么能确保一个线程分配了内存指针没修改的时候另一个线程又分配内存不会覆盖之前的内存呢?这里有一种方法,让每一个线程在堆中先预分配一小块内存(TLAB本地线程分配缓冲),每个线程只在自己的内存中分配内存。 最后,对象被成功分配内存。我们知道通过一个对象,我们可以通过getClass()方法获取类,默认比较两个对象实际比较的是对象内存的哈希值,这又是怎么实现的呢?其实在分配完内存后,虚拟机会对对象进行必要的设置,对象的类,对象的哈希码等信息都存放在对象的对象头中,所以分配的内存大小绝不止属性的总和。

0 0