java基础(参考多个文章和内容整合复习以下的都非本人写)

1.Java程序运行原理

Class文件内容
class文件包含JAVAC程序执行的字节码;数据严格按照格式紧凑排列在class文件中的二进制流,中间无任何分隔符;文件开头有一个Oxcafebabe(16进制)特殊的一个标志。
java基础(参考多个文章和内容整合复习以下的都非本人写)java基础(参考多个文章和内容整合复习以下的都非本人写)
方法区:
jvm用来存储加载的类信息、常量、静态变量、编译后代码等数据虚拟机规范中这是一个逻辑区划。具体实现根据不同的虚拟机来实现。
如:oracle的HotSpot在java7中方法区放在永久代,java8放在元数据空间,并通过GC机制付这个区域进行管理。

堆内存:
Java 虚拟机所管理的内存中最大的一块,Java 堆是所有线程共享的一块内存区域,在虚拟机启动时创建。此内存区域的唯一目的就是存放对象实例,几乎所有的对象实例以及数组都在这里分配内存。
.从垃圾回收的角度,由于现在收集器基本都采用分代垃圾收集算法,所以 Java 堆还可以细分为:新生代和老年代:再细致一点有:Eden 空间、From Survivor、To Survivor 空间等。进一步划分的目的是更好地回收内存,或者更快地分配内存。 OutOfMemoryError
Java 虚拟机栈
也是线程私有的,它的生命周期和线程相同,描述的是 Java 方法执行的内存模型,每次方法调用的数据都是通过栈传递的。每个线程都有独立的空间,线程栈由多个栈贴组成,一个线程执行一个或多个方法,一个方法一个栈帖,栈内默认最大1M,而每个栈帧中都拥有:局部变量表、操作数栈、动态链接、方法出口信息。
Java 虚拟机栈会出现两种错误:StackOverFlowError 和 OutOfMemoryError。

StackOverFlowError: 若 Java 虚拟机栈的内存大小不允许动态扩展,那么当线程请求栈的深度超过当前 Java 虚拟机栈的最大深度的时候,就抛出 StackOverFlowError 错误。
OutOfMemoryError: 若 Java 虚拟机栈的内存大小允许动态扩展,且当线程请求栈时内存用完了,无法再动态扩展了,此时抛出 OutOfMemoryError 错误。
每个 Java 方法在执行的同时会创建一个栈帧用于存储局部变量表、操作数栈、常量池引用等信息。从方法调用直至执行完成的过程,就对应着一个栈帧在 Java 虚拟机栈中入栈和出栈的过程。
本地方法栈
和虚拟机栈所发挥的作用非常相似,区别是: 虚拟机栈为虚拟机执行 Java 方法 (也就是字节码)服务,而本地方法栈则为虚拟机使用到的 Native 方法服务。 在 HotSpot 虚拟机中和 Java 虚拟机栈合二为一。

本地方法被执行的时候,在本地方法栈也会创建一个栈帧,用于存放该本地方法的局部变量表、操作数栈、动态链接、出口信息。

方法执行完毕后相应的栈帧也会出栈并释放内存空间,也会出现 StackOverFlowError 和 OutOfMemoryError 两种错误。
程序计数器
程序计数器是一块较小的内存空间,可以看作是当前线程所执行的字节码的行号指示器。字节码解释器工作时通过改变这个计数器的值来选取下一条需要执行的字节码指令,分支、循环、跳转、异常处理、线程恢复等功能都需要依赖这个计数器来完成。

Java 虚拟机所管理的内存中最大的一块,Java 堆是所有线程共享的一块内存区域,在虚拟机启动时创建。此内存区域的唯一目的就是存放对象实例,几乎所有的对象实例以及数组都在这里分配内存。

java基础(参考多个文章和内容整合复习以下的都非本人写)
java基础(参考多个文章和内容整合复习以下的都非本人写)
jvm从方法区获取字节码指令 程序计数器记住当前线程执行位置 入虚拟机操作栈。
何为线程?
线程与进程相似,但线程是一个比进程更小的执行单位。一个进程在其执行的过程中可以产生多个线程。与进程不同的是同类的多个线程共享进程的堆和方法区资源,但每个线程有自己的程序计数器、虚拟机栈和本地方法栈,所以系统在产生一个线程,或是在各个线程之间作切换工作时,负担要比进程小得多,也正因为如此,线程也被称为轻量级进程。
线程状态:
1 new 2 runnable 3 blocked 4 Wating 5 TimedWating 6 Terminated

java基础(参考多个文章和内容整合复习以下的都非本人写)
线程中止
旧的:stop终止线程,并清除监控器锁的信息但是肯能导致线程安全问题

java基础(参考多个文章和内容整合复习以下的都非本人写)
2.interrupt
其对object join wait sleep方法有效 抛出interptRxception
io或nio的channel阻塞

线程通信:个个线程之间的协同
通信的方式:
1文件共享
2网络共享
3共享变量
4jdk童工的线程协调api(suspend/reesume, wait/notify, part/unpark)
suspend/reesume 已经弃用 容易顺序和同步代码死锁
wait/notify 顺序有要求 notify先掉wait后线程永远处于waiting状态
part/unpark 不要求顺序但对sysinorized同步代码会处于waiting状态

线程封闭:ThreadLocal ,局部变量
ThreadLocal线程级别变量
局部变量 :位于线程栈中,其他线程无法访问这个栈。
线程池:

java基础(参考多个文章和内容整合复习以下的都非本人写)

线程池原理:

java基础(参考多个文章和内容整合复习以下的都非本人写)
keepAliveTime:有效时间(是当最大的线程数大于核心线程数,且队列数加上核心线程数小于最大线程数,当加入的线程数大于核心和对列的总数,当再加入线程时,就会创建线程数,并当大于核心线程创建的线程其空闲的有效时间后销毁。)
corePoolSize:核心线程数
BlockingQueue:队列线程数
maximumPoolSize:最大线程数
当核心线程数没满的话就创建线程执行-》核心线程满的话就判断队列有没有满->没满入到队列->有就去判断最大线程数是否已经满了,没满就新建线程执行,有满就报异常。
核心线程:
Executors.newFixedThreadPool(int nThreads)其原理就是
ThreadPoolExecutor threadPoolExecutor = new ThreadPoolExecutor(5, 5, 0L, TimeUnit.MILLISECONDS,
new LinkedBlockingQueue());
corePoolSize等于maximumPoolSize
keepAliveTime为0
BlockingQueue workQueue队列是无界的int的默认最大值2147483647

如当前给其5个核心线程当核心线程满的话,其他的超出直接加入队列中。

Executors.newCachedThreadPool()

return new ThreadPoolExecutor(0, 2147483647, 60L, TimeUnit.SECONDS, new SynchronousQueue());
corePoolSize为:0
maximumPoolSize为: Integer.MAX_VALUE 2147483647 最大线程数相当于无界的。
keepAliveTime:60L 秒TimeUnit.SECONDS,
BlockingQueue workQueue 队列的new SynchronousQueue() 一进一出