同步操作将从 Java精选/Ebooks 强制同步,此操作会覆盖自 Fork 仓库以来所做的任何修改,且无法恢复!!!
确定后同步将在后台操作,完成时将刷新页面,请耐心等待。
所有进程都使用寄存器,Java虚拟机使用下列寄存器管理系统堆栈:
程序记数寄存器:跟踪程序执行的准确位置
堆栈指针寄存器:指示操作栈项
框架寄存器:指向当前执行的环境
变量寄存器:指向当前执行环境中第一个本地变量
Java开发组决定Java只使用四个寄存器,这是因为如果使用的寄存器数多于处理器端口数,那么处理器的效率将严重地降低。
Java虚拟机中的堆栈用于存放变量,Java程序向Java虚拟机传递字节码,Java虚拟机为每个方法创建堆栈框架,每个框架维护三种信息:
1)局部变量:由变量寄存器指向的32位变量数组。 2)执行环境:由框架寄存器指向和执行的方法。 3)操作堆栈:执行先进先出规则(FIFO),它是32位宽度的,它为操作码维护必要的参数,该堆栈的顶部是由堆栈指针寄存器索引的。
寄存器位于处理器内部,这一点和其他的存储媒介都不一样。不过寄存器个数是有限的。在内存中的寄存器区域是由编译器根据需要来分配的。程序开发人员不能够通过代码来控制这个寄存器的分配。
1、现实使用中易出问题。
由于永久代内存经常不够用或者发生内存泄露,爆出异常java.lang.OutOfMemoryError: PermGen。
字符串存在永久代中,容易出现性能问题和内存溢出。
类及方法的信息等比较难确定其大小,因此对于永久代的大小指定比较困难,太小容易出现永久代溢出,太大则容易导致老年代溢出。
2、永久代会位GC带来不必要的复杂度,而且回收效率偏低。
3、Oracle可能会将HotSpot和JRockit合二为一。
参照JEP122原文截取:
Motivation
This is part of the JRockit and Hotspot convergence effort.
JRockit customers do not need to configure the permanent
generation (since JRockit does not have a permanent generation)
and are accustomed to not configuring the permanent generation.
即:移除永久代是为融合HotSpot JVM与 JRockit VM而做出的努力,因为JRockit没有永久代,不需要配置永久代。
Java中int类型变量的长度是一个固定值与平台无关,都是32位。
意思就是说在32位和64位的Java虚拟机中int类型的长度是相同的。
Garbage first垃圾收集器是目前垃圾收集器理论发展的最前沿成果,相比与CMS收集器。
G1收集器两个最突出的改进是:
1、基于标记-整理算法,不产生内存碎片。
2、可以非常精确控制停顿时间,在不牺牲吞吐量前提下,实现低停顿垃圾回收。
G1收集器避免全区域垃圾收集,它把堆内存划分为大小固定的几个独立区域,并且跟踪这些区域的垃圾收集进度,同时在后台维护一个优先级列表,每次根据所允许的收集时间, 优先回收垃圾最多的区域。
区域划分和优先级区域回收机制,确保G1收集器可以在有限时间获得最高的垃圾收集效率
虚引用与其他几种引用都不同,虚引用不会决定对象的生命周期。如果一个对象仅有虚引用,那么就和没有任何引用一样,在任何时候都可能被垃圾回收器回收。
虚引用需要使用PhantomReference类来实现,不能单独使用必须和引用队列联合使用。虚引用的应用场景是跟踪对象被垃圾回收的状态。
String str = new String("abc");
ReferenceQueue queue = new ReferenceQueue();// 虚引用必须与一个引用队列关联
PhantomReference pr = new PhantomReference(str, queue);
Concurrent mark sweep(CMS)收集器是一种年老代垃圾收集器,其最主要目标是获取最短垃圾回收停顿时间, 和其他年老代使用标记-整理算法不同,它使用多线程的标记-清除算法。最短的垃圾收集停顿时间可以为交互比较高的程序提高用户体验。CMS工作机制相比其他的垃圾收集器来说更复杂。
整个过程分为以下4个阶段:
初始标记
只是标记一下 GC Roots 能直接关联的对象,速度很快,仍然需要暂停所有的工作线程。
并发标记
进行 GC Roots 跟踪的过程,和用户线程一起工作,不需要暂停工作线程。
重新标记
为了修正在并发标记期间,因用户程序继续运行而导致标记产生变动的那一部分对象的标记记录,仍然需要暂停所有的工作线程。
并发清除
清除GC Roots不可达对象,和用户线程一起工作,不需要暂停工作线程。由于耗时最长的并发标记和并发清除过程中,垃圾收集线程可以和用户现在一起并发工作, 所以总体上来看CMS收集器的内存回收和用户线程是一起并发地执行。
DGC叫做分布式垃圾回收。
RMI使用DGC来做自动垃圾回收。
因为RMI包含了跨虚拟机的远程对象的引用,垃圾回收是很困难的。
DGC使用引用计数算法来给远程对象提供自动内存管理。
不同回收器不同:Serial、ParNew会暂停用户所有线程工作;CMS、G1会在某一阶段暂停用户线程。
内存分配策略
对象优先在Eden分配:若Eden无空间,Java虚拟机发起一次Minor GC。
大对象直接进入老年代:大对象指需要大量连续内存空间的对象(如长数组、长字符串)。
长期存活的对象进入老年代:每个对象有一个对象年龄计数器,age=15晋升为老年代。age+1的两个情况:对象在Eden出生并经过一次Minor GC存活且被survivor容纳;在survivor区经历过一次minor GC。
在需要释放内存的地方调用finalize(),则在下一轮垃圾回收时会回收占用的内存,一般情况下不需要显式调用此函数。
垃圾回收器只能回收那些由new关键字创建的对象所占用的内存,那么有些不是通过这种方式(比如调用C++本地方法)所占用的内存如何回收呢?那么就需要使用finalize()了。
由于C++中需要使用free()函数来释放内存,所以Java程序在调用C++时需要调用finalize()方法来释放内存。
Java对象由三个部分组成:对象头、实例数据、对齐填充。
对象头由两部分组成:
第一部分存储对象自身的运行时数据:哈希码、GC分代年龄、锁标识状态、线程持有的锁、偏向线程ID(一般占32/64 bit)。
第二部分是指针类型,指向对象的类元数据类型(即对象代表哪个类)。
如果是数组对象,则对象头中还有一部分用来记录数组长度。
实例数据用来存储对象真正的有效信息(包括父类继承下来的和自己定义的) 对齐填充:JVM要求对象起始地址必须是8字节的整数倍(8字节对齐)。
此处可能存在不合适展示的内容,页面不予展示。您可通过相关编辑功能自查并修改。
如您确认内容无涉及 不当用语 / 纯广告导流 / 暴力 / 低俗色情 / 侵权 / 盗版 / 虚假 / 无价值内容或违法国家有关法律法规的内容,可点击提交进行申诉,我们将尽快为您处理。