《深入理解Java虚拟机》-读书笔记-第二章-Java内存区域与内存溢出异常-更新中

线索栏笔记栏
Java运行时数据区域包括哪些?运行时数据区【运行时的数据】,执行引擎【编译执行还是解释执行还是共存】,本地方法库【提供调用操作系统或其他底层语言的功能】
如果让你设计一个运行时数据区域,你如何设计?按照职责将内存区域划分开。
首先,我们想要运行数据,那么需要将类信息保存下来,那么【暂定叫他 存类区】。
其次,如果我们想要运行,那么借鉴计算机本身的栈操作思想,需要一个栈来保存我们当前调用函数时的变量,计算结果,等到调用函数结束时,弹出该栈即可【暂定叫它 栈区
接着,如果我们想要程序可以并发执行,那么就需要调用操作系统的能力来创建线程【本地方法区域】。

接着,并发程序涉及上下文切换,此时就需要使用程序计数器记录自己执行到了哪一步。【此时设计一个值得思考的点,那就是,操作系统肯定提供了线程,Java只是调用操作系统接口创建的线程,那么按道理来说,“线程”这个数据结构应该是Java在OS之上包裹了一个“Java线程结构”,那么当前线程的所有数据引用肯定是需要保存在一个地方的,执行的位置也需要保存,那么,为什么不将对于数据的引用和执行的位置保存在一个地方,不对外暴露,而是只将程序计数器暴露出来,可能等我后续阅读更深之后才能知晓】。

再其次,如果用到对象,我们需要一部分空间来保存对象。此处思考一个问题,我们很容易想到,一个对象,可能被线程共享也可能不被共享【不被共享的对象,在栈区创建就好了,用完直接销毁】;那么被线程共享的对象呢?【需要设计一个存放可以共享对象的区域,叫做堆】
解释一下什么是线程私有?
什么是线程共享?
Java是如何实现的?
线程私有:线程自己执行的位置,执行时的数据,都只有线程自己可以看到和修改,和其他线程互不影响。【你家和你邻居都在一个小区里,但是一般互不影响对方的生活。】
线程共享:线程执行时使用的数据,其他线程可能会进行修改和读取。【你们小区的卫生间,你上一秒看的时候还没有人,下一秒可能就有人了。】

如何实现的:线程本身由操作系统支持,操作系统实现了底层的线程,Java直接调用就可以了,线程本身是存在进程之间的,你可以想象为如下【代码一】的情况
所以,线程自己的东西保存在自己私有的区域就可以了,如pc的值,当前线程的栈的数据等;其他的数据,可能就是放在进程的内存里了,这个进程的线程都可以看到和修改;【可能不严谨,等我后续更新。】
Java运行时数据区域可能存在的内存异常有哪些?
为什么会出现这种内存异常?
程序计数器:不会出现内存异常。【只是个人猜测:程序计数器,按道理应该是跟随线程来的,就是说线程创建完毕,肯定就会有程序计数器的空间。所以不会存在程序计数器的异常。那你可能会问?“那我创建完线程发现没空间给程序计数器了咋办呢?”。我猜测Java,或者说操作系统,会在创建线程的时候,检测空间是不是足够放基本的线程数据,你可以理解为【代码二】的代码。然后才会去创建,也就是说,只要能创建出来,那么肯定就有程序计数器的空间。(有我吃的,就有你们喝的)】

虚拟机栈

代码1

class 进程 {
    线程[] threadArray;
}

class 线程 {
    // 操作系统程序计数器的值
    int pc;
    // 当前线程的栈的数据
    Object[] stackData;
    // 线程运行时一些数据
    Object[] data;
    // ...其他数据【我还没仔细看】
}

代码二

class 线程 {
    // 程序计数器
    int pc;
    // ...省略
    
    public 线程() {
        // 检测是否空间足够放下pc,等其他数据
        if (isMemoryNotEnough()) {
            throw new Exception("没空间创建线程了");
        }
        this.pc = 0;
        // ...省略
    }
}
  • 2
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值