同步操作将从 Java精选/Ebooks 强制同步,此操作会覆盖自 Fork 仓库以来所做的任何修改,且无法恢复!!!
确定后同步将在后台操作,完成时将刷新页面,请耐心等待。
分为新生代和老年代,新生代默认占总空间的1/3,老年代默认占2/3。
新生代使用复制算法,有3个分区:Eden、To Survivor、From Survivor,它们的默认占比是8:1:1。
当新生代中的Eden区内存不足时,就会触发Minor GC,过程如下:
1、在Eden区执行了第一次GC之后,存活的对象会被移动到其中一个Survivor分区;
2、Eden区再次GC,这时会采用复制算法,将Eden和from区一起清理,存活的对象会被复制到to区;
3、移动一次,对象年龄加1,对象年龄大于一定阀值会直接移动到老年代;
4、Survivor区相同年龄所有对象大小的总和(Survivor区内存大小*这个目标使用率)时,大于或等于该年龄的对象直接进入老年代。其中这个使用率通过-XX:TargetSurvivorRatio指定,默认为50%;
5、Survivor区内存不足会发生担保分配;
6、超过指定大小的对象可以直接进入老年代;
Major GC,指的是老年代的垃圾清理,但并未找到明确说明何时在进行MajorGC。
FullGC,整个堆的垃圾收集,触发条件:
1、每次晋升到老年代的对象平均大小>老年代剩余空间;
2、MinorGC后存活的对象超过了老年代剩余空间;
3、元空间不足;
4、System.gc()可能会引起;
5、CMS GC异常,promotion failed:MinorGC时,survivor空间放不下,对象只能放入老年代,而老年代也放不下造成;concurrent mode failure:GC时,同时有对象要放入老年代,而老年代空间不足造成;
6、堆内存分配很大的对象。
Java语言中一个显著的特点就是引入了垃圾回收机制,使C++程序员最头疼的内存管理的问题迎刃而解,它使得Java程序员在编写程序的时候不再需要考虑内存管理。由于有个垃圾回收机制,Java中的对象不再有“作用域”的概念,只有对象的引用才有"作用域"。
垃圾回收可以有效的防止内存泄露,有效的使用可以使用的内存。垃圾回收器通常是作为一个单独的低级别的线程运行,不可预知的情况下对内存堆中已经死亡的或者长时间没有使用的对象进行清楚和回收,程序员不能实时的调用垃圾回收器对某个对象或所有对象进行垃圾回收。
回收机制有分代复制垃圾回收和标记垃圾回收,增量垃圾回收。
内存溢出:OutOfMemory,指程序在申请内存时,没有足够的内存空间供其使用。
内存泄露:Memory Leak,指程序在申请内存后,无法释放已申请的内存空间,内存泄漏最终将导致内存溢出。
常见的 GC 日志开启参数包括:
1、 -Xloggc:filename,指定日志文件路径
2、 -XX:+PrintGC,打印 GC 基本信息
3、 -XX:+PrintGCDetails,打印 GC 详细信息
4、 -XX:+PrintGCTimeStamps,打印 GC 时间戳
5、 -XX:+PrintGCDateStamps,打印 GC 日期与时间
6、 -XX:+PrintHeapAtGC,打印 GC 前后的堆、方法区、元空间可用容量变化
7、 -XX:+PrintTenuringDistribution,打印熬过收集后剩余对象的年龄分布信息,有助于 MaxTenuringThreshold 参数调优设置
8、 -XX:+PrintAdaptiveSizePolicy,打印收集器自动设置堆空间各分代区域大小、收集目标等自动调节的相关信息
9、 -XX:+PrintGCApplicationConcurrentTime,打印 GC 过程中用户线程并发时间
10、 -XX:+PrintGCApplicationStoppedTime,打印 GC 过程中用户线程停顿时间
11、 -XX:+HeapDumpOnOutOfMemoryError,堆 oom 时自动 dump
12、 -XX:HeapDumpPath,堆 oom 时 dump 文件路径
Java 9 JVM 日志模块进行了重构,参数格式发生变化,这个需要知道。
GC 日志输出的格式,会随着上面的参数不同而发生变化。关注各个分代的内存使用情况、垃圾回收次数、垃圾回收的原因、垃圾回收占用的时间、吞吐量、用户线程停顿时间。
借助工具可视化工具可以更方便的分析,在线工具 GCeasy;离线版可以使用 GCViewer。
如果现场环境不允许,可以使用 JDK 自带的 jstat 工具监控观察 GC 情况。
通常我们定义一个基本数据类型的变量,一个对象的引用,还有就是函数调用的现场保存都使用内存中的栈空间;而通过new关键字和构造器创建的对象放在堆空间;程序中的字面量(literal)如直接书写的100、“hello”和常量都是放在静态存储区中。栈空间操作最快但是也很小,通常大量的对象都是放在堆空间,整个内存包括硬盘上的虚拟内存都可以被当成堆空间来使用。
String str = newString("hello");
上面的语句中str放在栈上,用new创建出来的字符串对象放在堆上,而“hello”这个字面量放在静态存储区。
补充:较新版本的Java中使用了一项叫“逃逸分析“的技术,可以将一些局部对象放在栈上以提升对象的操作性能。
JVM:类加载器(ClassLoader)、运行时数据区(Runtime Data Area)、执行引擎(Execution Engine)、本地库接口(Native Interface)。
组件的作用:首先通过类加载器(ClassLoader)会把 Java 代码转换成字节码,运行时数据区(Runtime Data Area)再把字节码加载到内存中,而字节码文件只是 JVM 的一套指令集规范,并不能直接交个底层操作系统去执行,因此需要特定的命令解析器执行引擎(Execution Engine),将字节码翻译成底层系统指令,再交由 CPU 去执行,而这个过程中需要调用其他语言的本地库接口(Native Interface)来实现整个程序的功能。
Java提供了一种叫做对象序列化的机制,它把对象表示成一连串的字节,里面包含了对象的数据,对象的类型信息,对象内部的数据的类型信息等等。
因此,序列化可以看成是为了把对象存储在磁盘上或者是从磁盘上读出来并重建对象而把对象扁平化的一种方式。
反序列化是把对象从扁平状态转化成活动对象的相反的步骤。
当应用程序希望把内存对象跨网络传递到另一台主机或者是持久化到存储的时候,就必须要把对象在内存里面的表示转化成合适的格式。这个过程就叫做Marshalling,反之就是demarshalling。
RMISecurityManager使用下载好的代码提供可被RMI应用程序使用的安全管理器。
如果没有设置安全管理器,RMI的类加载器就不会从远程下载任何的类。
DGC叫做分布式垃圾回收。
RMI使用DGC来做自动垃圾回收。
因为RMI包含了跨虚拟机的远程对象的引用,垃圾回收是很困难的。
DGC使用引用计数算法来给远程对象提供自动内存管理。
此处可能存在不合适展示的内容,页面不予展示。您可通过相关编辑功能自查并修改。
如您确认内容无涉及 不当用语 / 纯广告导流 / 暴力 / 低俗色情 / 侵权 / 盗版 / 虚假 / 无价值内容或违法国家有关法律法规的内容,可点击提交进行申诉,我们将尽快为您处理。