问题1:JAVA内存分配的方法?
方法一:指针碰撞,对象所需要的内存在类加载完成以后便可以确定,假设JAVA堆中内存是绝对规整的,所有用过的内存都放在一边,空闲的放到另一边,中间放着一个指针作为分界点,分配内存是通过指针的移动。使用Serial、ParNew等带有Compact过程的收集器时,系统采用指针碰撞。
方法二:空闲列表,如果JAVA堆中的内存并不是规整的,而是相互交错,虚拟机通过维护一个列表来记录哪些内存是可用的,哪些内存是不可用的。分配内存时从列表中找到一块足够大的空间来分配实例。使用CMS这种基于Mark-Sweep算法收集器时,采用空闲列表。
问题2:如何解决高并发情况下的内存分配?
如在给A分配内存时,指针还没来得及修改,对象B又同时使用了原来的指针来分配内存情况。解决这种问题有两种方案; 方案1:对分配内存空间的动作进行同步处理,实际上虚拟机采用CAS配上失败重试的方式保证更新操作的原子性。 方案2:内存分配的动作按照线程划分在不同的空间之中进行,即每个线程在JAVA堆中预先分配一小块内存,成为TLAB,哪个线程要分配内存,就在哪个线程的TLAB上分配,只有TLAB用完并分配新的TLAB时,才需要同步锁定