HotSpot中的对象

2019-02-09

1 对象创建过程

  1. 遇到new指令的时候,检查该指令的参数是否能在常量池中定位到一个类的符号引用,并检查这个类是否已加载、解析、初始化过,如果没有必须先进行类的加载过程(这个之后再整理);
  2. 分配内存。加载类之后一个对象所需的内存大小就确定了;使用Serial、ParNew等收集器时,堆内存是整齐的,所以使用指针碰撞划分内存,即在空闲内存的分界点开始分配指定大小的内存空间;如果用CMS等给予Mark-Sweep算法的收集器时,堆内存不规整,所以使用空闲列表划分内存,即JVM维护了一个记录可用内存的表,从列表中找一块足够大小的内存空间用于分配,并更新列表记录。
  3. 对于多线程同时创建对象时,指针可能出错,可以使用两种解决方案:
    • 对分配内存空间的动作进行同步,采用CAS+失败重试的方式可以保证操作的原子性。
    • 把内存分配动作按照线程划分在不同的空间之中进行,即每个线程在java对中预先分配一小块内存成为本地线程分配缓冲(Thread Local Allocation Buffer, TLAB)。当TLAB用完并分配新TLAB的时才需要同步锁定。
  4. 内存分配完成后,进行初始化零值(如果使用TLAB,可以在TLAB分配时进行);
  5. 虚拟机对对象进行设置,设置内容存放在对象头(Object Header);
  6. 执行方法。
Read More

设计模式的七大设计原则和三大分类

2019-02-08

1 设计模式的七大原则

1.1 单一职责原则

通俗的讲就是一个类只负责一项职责。就一个类而言,应该仅有一个引起它变化的原因,增加功能不应该修改已有的代码,避免修改出错及重复测试。如果你能够想到多于一个的动机去改变一个类,那么这个类就是具有多于一个的职责, 应该考虑类的职责分离。

Read More

Spark资源调度

2019-02-08

1 DAGScheduler

DAGScheduler把一个Spark作业转换成Stage的DAG(Directed Acyclic Graph有向无环图),根据RDD和Stage之间的关系找出开销最小的调度方法,然后把Stage以TaskSet的形式提交给TaskScheduler,下图展示了DAGScheduler的作用:

Read More