zoukankan      html  css  js  c++  java
  • JVM内存空间划分与作用详解

    在之前已经对Java的字节码进行了非常详细而又系统的学习了,接下来开启jvm内存相关的新篇章,在一个新知识开头之前肯定得理论化的对其进行一个整体的介绍,所以摒弃浮躁,先来看看相关的理论,主要是看一下JVM内存的相关结构:

    虚拟机栈:每一个方法在执行的过程中都会生成一个栈帧(Stack Frame,在之前【https://www.cnblogs.com/webor2006/p/9718062.html】已经有介绍过)这个数据结构。

    程序计数器(Program Counter):它占据的空间是比较小的,主要是描述线程执行字节码第一行执行完了之后,下一行字节码在哪。

    本地方法栈:主要用于处理本地方法。

    堆(Heap):这是JVM所管理最大的内存空间,在Java当中我们都是通用引用来操作对象的,而对象本身是位于堆上面,而引用则是位于虚拟机栈上面,所以引用本身是个变量,所以在Java中一定是通过引用来获取到这个对象然后去操纵它。下面用一个小的示意图来理论引用与对象它们之间的关系。

    其实引用指向对象是有两种形态的,上面只是一个粗略的形态,其实在堆中一部份存放的是对象实例本身的数据,另一部分则是元数据(也就是class数据),而元数据只有一份,它是存放在另外一个位置的,该位置叫方法区,如下:

    而实际实现第一种形态可能是这样:

    而第二种形态可能为:

    对于Oracle的Hotspot虚拟机采用的是第二种形态,那对于这二种形态有啥区别呢?其实区别还是挺大的,对于JVM垃圾回收来说,当对像被回收之后可能会造成对象的移动,用个形象的未例图来表述这个移动:

    对于对象的移动,假如采用第一种形态,由于是用一个指针来指向对象,所以指针的值也会发生变化,而对于堆内存而言发生垃圾回收的频率是相当之高的,所以该指向变量的指针会频繁发生变化;而如果采用第二种形态则没有这个问题,因为ref是直接指向的对象本身,当对象移动时则ref只是指向的位置会发生变化,值还是一样的,如下:

    所以经过对比,也能发现第二种形态会更好,这也是Oracle的Hotspot为啥采用第二种的原因。

    方法区(Method Area):存储元信息。我们对于垃圾收集器可能经常会听到一个叫永久代(Permanent Generation)的概念,所以永久代当然就是很少会被回收,所以会将方法区称为永久代,但是从JDK1.8开始,已经彻底废弃了永久代了,使用元空间(Meta Space)代替。

    运行时常量池:方法区的一部内容,这个在咱们之前的字节码学习中已经详细学习过。

    直接内存:Direct Memory,它并不是由JVM所管理的一块区域,而是由系统所管辖的,只不过是JVM向系统申请了这块内存。

    以上是从宏观的角度来审视JVM的内存结构,在之后会结合实践对这些理论进行进一步巩固!

  • 相关阅读:
    C++面向对象笔记:继承、派生
    教你制作伪静态
    安装android环境别忘了加个环境变量sdk_home
    javascript获取asp.net后台代码的方法
    一天学会PHP(转)
    access数据库里面用sql语句随机调用一条数据
    【转】 android sdk setup时出现:HTTPS SSL error , Server:10.159.192.62
    AutoCode下载及具体使用方法
    讲故事谈.NET委托:一个C#睡前的故事
    使用activeskin控件制作VB和易语言的皮肤的视频教程
  • 原文地址:https://www.cnblogs.com/webor2006/p/9876493.html
Copyright © 2011-2022 走看看