线索栏 | 笔记栏 |
---|---|
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;
// ...省略
}
}