java虚拟机(知识总结)

7 篇文章 0 订阅

java虚拟机

(本文章工作日周(1-5)会持续更新,如果你感觉本文章对您有用,可添加收藏方便查看.)
java虚拟机中包含:

  1. java虚拟机栈 - java虚拟机栈是线程私有的,它的生命周期与线程相同,栈中一般存放这基本数据类型(boolean,byte,char,short,int,float,long,double)、对象的引用(reference 类型,它不等同于对象的本身,它可能是一个指向对象的引用指针,也可能是代表对象的一个句柄,或者一个对象的相关的位置)、在java栈中64长度的long和double类型的数据会占用两个局部变量空间,其他只占用一个空间。且局部变量所需要的内存空间是在编译期间分配,在方法运行期间不会改变局部变量表的大小。
  2. java 堆 - 是被所有线程共享的一块内存区域,在虚拟机启动时创建.此内存区域的唯一目的,就是存放对象实例,所有的对象实例都是在这里进行分配的。(但是随着JIT编译器的发展,栈上分配、标量替换优化会导致一些微妙的变化,所有的对象实例都是在堆上分配也不是那么“绝对”了),java堆中分为:新生代、老年代(java 堆中可能划分出多个线程私有的分配缓冲区)
  3. 方法区:方法区与java堆一样,对线程都是共享的,它用于储存已经被虚拟机加载的类信息、常量、静态变量、即时编译器编译后的数据
  4. 运行时常量池:它属于方法区的一部分.Class文件除了有方法,接口,字段,版本,还有一项是信息常量池(用于存储编译期生成的字符引用和字面量),在运行期间也可以把新的常量放入其中,可以使用String.intern()方法。
  5. 直接内存:直接内存不属于虚拟机运行内存的一部分,但是这类内存一直被频繁使用,而且也会导致outOfMemoryError异常.在JDK1.4中新加入了NIO(New Input/Output)类,引入了一种基于通道与缓冲区的I/O方式。它可以使用Native函数库直接分配到堆内存外,然后通过一个存储在java堆对象的DirectBytebuffer对象作为这块内存的引用操作,这样可以在一些场景中大大提升性能、因为避免了在Java堆中来回复制数据.(但是Directbytebuffer实例对象的创建和销毁是及其麻烦的),虽然本机的直接内存不受java堆内存的限制,但是既然是内存还是会受到本机总内存(包括RAM以及SWAP区或者分页文件,大小以及处理器寻址控件)的限制,服务器管理员在配置虚拟机参数时,会根据实际内存设置-Xmx等信息参数,但经常去忽略直接内存,使得各个内存区域的总和大于物理内存的限制,从而导致扩展出现OutOfMemoryError异常。
  6. 对象创建虚拟机运行:当你使用new 指令创建对象,这时虚拟机会根据指令去常量池中检查,有没有这个类的符号引用,并且去检查这个类有没有被加载、解析过,如果没有则需要进行类的加载。当对象的类加载创建过,java堆会为该对象分配一个所需的大小内存,如果java堆中的内存是规整的,比如用过的内存分一边,没有用过的内存分一边而中间有一个指针作为分界点,那么这个指针则需要外空闲的地方挪动这个对象所需的大小,这种指针移动被我们称之为指针碰撞。如果java堆中不是规则有序的,那就没有办法进行简单的指针碰撞分配空间,这时候就需要虚拟机记录一下那些是用过的内存,那些是没有用过的内存,当创建对象分配内存时找到此对象所需要的大小空间进行记录分配,这种分配内存空间的方法叫做空间列表,内存空间是否规整,是由采用的垃圾收集器是否带有压缩整理的功能决定的,因此,Serial、ParNew等带Compact过程的收集是采用的指针碰撞,CMS这种基于Mark-Sweep的算法收集器的则用的是空间列表
  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值