分布式java应用(一)

来源:互联网 发布:图片浏览软件下载 编辑:程序博客网 时间:2024/05/22 05:17

这里写图片描述
分布式java应用: 大型应用通常会拆分为多个子系统来实现,对于java来说,这些子系统可能部署在同一台机器的多个不同的JVM中,也可能部署在不同的机器上,但这些子系统又不是完全独立的,要相互通信来共同实现业务功能,此类java应用即为分布式java应用。
这里写图片描述
SOA: 面向服务架构,它强调系统之间以标准的服务方式进行交互,各系统可采用不同的语言、不同的框架来实现,交互则全部通过服务的方式进行。
这里写图片描述
常量池: 存放了所有的Field名称、方法名、方法签名、类型名、代码以及class文件中的常量值。
类加载机制: .class文件加载到JVM,并形成Class对象的机制,之后应用就可对Class对象进行实例化并调用,类加载机制可在运行时动态加载外部的类、远程网络下载过来的class文件等。
类加载过程: 装载、链接和初始化。装载和链接过程完成后,即将二进制的字节码转换为Class对象;初始化过程不是类加载时必须触发的,但最迟必须在初次主动使用对象前执行。
这里写图片描述
类加载器
这里写图片描述

类执行机制

字节码解释执行:
这里写图片描述
client compiler(C1) 优化方案:

  • 方法内联
    把调用到的方法的指令 直接植入当前方法中。
  • 去虚拟化
    装载class文件后,进行类层次的分析,如发现类中的方法只提供一个实现类,那么对于调用了此方法的代码,也可进行方法内联。
  • 冗余削除
    在编译时,根据运行时状况进行代码折叠或削除。
    server compiler(C2) 优化方案:
    逃逸分析: 根据运行状况来判断方法中的变量是否会被外部读取。如不会则认为此变量是逃逸的,基于逃逸分析C2在编译时会做标量替换、栈上分配和同步削除等优化。

  • 标量替换
    用标量替换聚合量。

  • 栈上分配
    如果某变量没有逃逸,那么C2 会选择在栈上直接创建对象实例,而不是在JVM堆上。
  • 同步削除
    如果发现同步的对象未逃逸,C2 编译时会直接去掉同步(synchronized)。
    OSR(On Stack Replace)编译: 只替换循环代码体的入口。

  • 回边计数器:方法中循环执行部分代码的执行次数。

  • 调用计数器:方法被调用的次数。

jvm内存管理

这里写图片描述
方法区(全局共享): 存放了要加载的类的信息、类中的静态变量、类中定义为final类型的常量、类中的Field信息、类中的方法信息。
在Sun JDK中这块区域对应Permanet Generation,默认最小值为16M,最大值为64M,可通过-XX:PermSize-XX:MaxPermSize来指定最大值和最小值。
堆: 存储对象实例和数组值。可通过-Xms-Xmx 控制大小。-XX:MinHeapFreeRatio= 来控制堆的动态扩容。
1. 新生代: 大多数情况下java中新建的对象都在此分配内存
这里写图片描述
可通过-Xmn 来控制新生代大小;通过-XX:SurvivorRatio 来控制Eden Space和Survivor Space的大小。
2. 旧生代: 用于存放新生代中经过多次GC后仍然存活的对象。新建的对象也有可能在旧生代上直接分配内存(由不同的GC实现决定):大对象(通过-XX:PretenureSizeThreshold=1024 (K,默认0)来代表当对象超过多大时就不在新生代分配而直接在旧生代分配(对Parallel Scavenge GC无效));大的数组对象,且数组中无引用外部对象。
本地方法栈: 用于支持native方法的执行,存储了每个native方法调用的状态,在Sun JDK的实现中本地方法栈和JVM方法栈是同一个。
PC寄存器和JVM方法栈: 每个线程均会创建PC寄存器和JVM方法栈。JVM方法栈为线程私有,当方法运行完毕时,起对应的栈帧所占用的内存会自动释放。在Sun JDK中通过-Xss 来指定其大小。

内存分配

TLAB(Thread Local Allocation Buffer): Sun JDK为每个新创建的线程在新生代的Eden Space上分配的一块独立的空间,其大小由JVM根据运行情况计算得到,可通过-XX:TLABWasteTargetPercent 来设置TLAB可占用的Eden Space的百分比,默认为1%;在TLAB上分配内存时不需要加锁(由于堆是线程共享,所以在堆上分配内存时需要加锁),为优先选择,如果对象过大或者TLAB空间已用完,仍在堆上进行分配。可通过-XX:PrintTLAB 查看TLAB空间使用情况。

堆分配、基于逃逸分析直接在栈上进行分配。

内存回收