内部机构:
方法区:类常量池 静态常量池static
栈区(先入后出):方法进出
堆区:包含对象在内的各种变量
本地方法栈:进行衔接,程序转化成操作系统内核的方法,最后转化成硬件。不是java独有的而是所有高级语言甚至c语言都应该具备的.关键点不是在于编程语言,而是在于计算机的体系思想。在栈区内的一些辅助线程可以负责翻译,还有一些线程负责回收没用的数据,称作守护线程。最终的线程是本地方法栈的线程。
每个方法本质上也是个栈结构。变量的作用域就由此而来,花括号就是在入栈出栈起点和终点。
下面是一个代码示例
test类
person类
car类
三个类在内存中的示例图
当上图x1中的值发生改变的时候。
当修改x2.arr2的时候,这个数组有了新的指向,之前指向的4442被销毁,标记为无效并自动回收。堆中的数据没有被指向的时候就会被回收,但是常量池不会,除非空间实在不够的时候,没有被引用的字符串常量会被删掉。非静态方法从对象中拷贝一份入栈。
在内存中,同一个方法里的两个相邻变量地址大概率也相邻。
引用类型相等代表他们指向相同的地址。
像下面这种情况,x1x2相互指向再置空,虽然两个地址相互指向但是仍然会被内存清除。这是面试点
这两个相互指向的地址会被清除
static类型方法在静态常量池中,可以直接调用,但是不是static类型的需要先new一个对象,通过对象调用
凡是static修饰的,只在常量池中有一份,不被static修饰的在每个对象中都有一份,可以用多线程测试。
一个栈里不断有方法进出就是线程。创建线程之后谁也不等谁,交错进行,如下等号和井号交错输出。
cpu某个核同一时刻只能处理一件事,防止电压叠加。不能两个同时执行,否则会对另一个造成破坏。
不同的线程可以对同一个变量进行操作。
进入就绪态的线程才能被cpu选中执行,每个线程执行一个时间片,执行完就结束,没执行完就保留当前状态等再次执行,不是先进入就绪态先执行。
可以用synchronized锁住方法,谁调用方法,谁就独占整个对象。但如果是两个对象就互不影响。
程序计数器可以辅助栈,什么时候入栈出栈,它负责计数