- 921. Minimum Add to Make Parentheses Valid 使括号有效的最少添加
- 915. Partition Array into Disjoint Intervals 分割数组
- 932. Beautiful Array 漂亮数组
- 940. Distinct Subsequences II 不同的子序列 II
已知,平时系统运行创建的对象,除非是那种大对象,否则通常来说都是优先分配在新生代中的Eden区域的。
而且新生代还有另外两块Survivor区域,默认Eden区域占据新生代的80%,每块Survivor区域占据新生代的10%。
比如我们用以下JVM参数来运行代码:
-XX:NewSize=5242880 -XX:MaxNewSize=5242880 -XX:InitialHeapSize=10485760 -XX:MaxHeapSize=10485760 -XX:SurvivorRatio=8 -XX:PretenureSizeThreshold=10485760 -XX:+UseParNewGC -XX:+UseConcMarkSweepGC
上述参数都是基于JDK 1.8 版本来设置的,不同的JDK版本对应的参数名称是不一样的,但是基本意思一致。
上面“-XX:InitialHeapSize” 和 “-XX:MaxHeapSize” 就是初始堆大小和最大对大小, “-XX:NewSize” 和“-XX:MaxNewSize” 是初始新生代大小和最大新生代大小,“-XX:PretenureSizeThreshold=10485760 ” 指定了大对象阈值是10MB。
相当于给堆内存分配10MB内存空间,其中新生代是5MB内存空间,其中Eden区占4MB,每个Survivor区占0.5 MB,大对象必须超过10MB才会直接进入老年代,年轻代使用 ParNew垃圾回收器,老年代使用CMS垃圾回收器,如下图:
我们需要在系统的JVM参数中加入GC日志的打印选型,如下所示:
1、 -XX:+PrintGCDetails:打印详细的GC日志;
2、 -XX:+PrintGCTimeStamps:这个参数可以打印出来每次GC发生的时间;
3、 -Xloggc:gc.log:这个参数可以设置将GC日志写入一个磁盘文件;
加上这几个参数后,JVM参数如下所示:
-XX:NewSize=5242880 -XX:MaxNewSize=5242880 -XX:InitialHeapSize=10485760 -XX:MaxHeapSize=10485760 -XX:SurvivorRatio=8 -XX:PretenureSizeThreshold=10485760 -XX:+UseParNewGC -XX:+UseConcMarkSweepGC -XX:+PrintGCDetails -XX:+PrintGCTimeStamps -Xloggc:gc.log
以下是当前的示例程序代码:
public class Demo1 {
public static void main(String[] args){
byte[] array1 = new byte[1024 * 1024];
array1 = new byte[1024 * 1024];
array1 = new byte[1024 * 1024];
array1 = null;
byte[] array2 = new byte[2 * 1024 * 1024];
}
}
上面的这段代码,先通过 “new byte[1024 * 1024]” 这样的代码连续分配了3个数组,每个数组都是1MB。
然后通过array1这个局部变量依次引用这三个对象,最后还把array1这个局部变量指向了null。
那么在JVM中上述代码是如何运行的呢?
首先看第一行代码: byte[] array1 = new byte[1024 * 1024]; 。
这行代码一旦运行,就会在JVM的Eden区内放入一个1MB的对象,同时在main线程的虚拟机栈中会压入一个 main() 方法的栈帧,在 main() 方法的栈帧内部,会有一个“array1” 变量,这个变量是指向堆内存 Eden 区的那个1MB的数组,如下图。
接着看第二行代码: array1 = new byte[1024 *1024];。
此时会在堆内存的Eden区中创建第二个数组,并且让局部变量指向第二个数组,然后第一个数组就没人引用了,此时第一个数组就成了没人引用的 “垃圾对象”了,如下图所示。
然后看第三行代码: byte[] array1 = new byte[1024 * 1024];。
这行代码在堆内存的Eden区内创建了第三个数组,同时让 array1 变量指向了第三个数组,此时前面两个数组都没有人引用了,就都成了垃圾对象,如下所示:
接着我们来看第四行代码: array1 = null;。
这行代码一致性,就让 array1 这个变量什么都不指向了,此时会导致之前创建的3个数组全部变成垃圾对象,如下图:
最后看第五行代码: byte[] array2 = new byte[2 * 1024 *1024];。
此时会分配一个2MB大小的数组,尝试放入Eden区中。
而这个时候 Eden 区明显是放不下的,因为Eden区总共就 4MB大小,而且里面已经放入了 3个 1MB的数组了,所以剩余空间只有 1MB了,此时你放一个 2MB的数组是放不下的。
所以这个时候就会触发年轻代的 Young GC。
在Eclipse等开发工具里如何以指定 JVM 参数运行程序,就是对你的程序右键,然后选择 “Run As -> Run Configurations” ,接着在下图中填入对应的JVM参数:
然后运行即可,此时运行完毕后,会在下述工程目录中出现一个 gc.log 文件,里面就是本次程序运行的 gc 日志,如下图所示:
打开gc.log文件,就会看到如下所示的gc日志:
Java HotSpot(TM) 64-Bit Server VM (25.111-b14) for windows-amd64 JRE (1.8.0_111-b14), built on Sep 22 2016 19:24:05 by "java_re" with MS VC++ 10.0 (VS2010)
Memory: 4k page, physical 16192480k(8225436k free), swap 24925816k(12234880k free)
CommandLine flags: -XX:InitialHeapSize=10485760 -XX:MaxHeapSize=10485760 -XX:MaxNewSize=5242880 -XX:NewSize=5242880 -XX:OldPLABSize=16 -XX:PretenureSizeThreshold=10485760 -XX:+PrintGC -XX:+PrintGCDetails -XX:+PrintGCTimeStamps -XX:SurvivorRatio=8 -XX:+UseCompressedClassPointers -XX:+UseCompressedOops -XX:+UseConcMarkSweepGC -XX:-UseLargePagesIndividualAllocation -XX:+UseParNewGC
0.112: [GC (Allocation Failure) 0.112: [ParNew: 3930K->512K(4608K), 0.0016424 secs] 3930K->551K(9728K), 0.0018267 secs] [Times: user=0.00 sys=0.00, real=0.00 secs]
Heap
par new generation total 4608K, used 2601K [0x00000000ff600000, 0x00000000ffb00000, 0x00000000ffb00000)
eden space 4096K, 51% used [0x00000000ff600000, 0x00000000ff80a558, 0x00000000ffa00000)
from space 512K, 100% used [0x00000000ffa80000, 0x00000000ffb00000, 0x00000000ffb00000)
to space 512K, 0% used [0x00000000ffa00000, 0x00000000ffa00000, 0x00000000ffa80000)
concurrent mark-sweep generation total 5120K, used 39K [0x00000000ffb00000, 0x0000000100000000, 0x0000000100000000)
Metaspace used 2651K, capacity 4486K, committed 4864K, reserved 1056768K
class space used 286K, capacity 386K, committed 512K, reserved 1048576K
初步分析日志结果:
1、 老年代5MB空间大于3MB,可以直接YoungGC,3M垃圾直接回收,Eden区清空,S1、S2也清空但根据日志,实际上fromspace是占满了这里很疑惑;
2、 根据日志,发现确实进行了一次YoungGC具体日志:0.112:[GC(AllocationFailure)0.112:[ParNew:3930K->512K(4608K),0.0016424secs]3930K->551K(9728K),0.0018267secs][Times:user=0.00sys=0.00,real=0.00secs]日中AllocationFailure表明了GC的原因(连续内存空间不足,内存空间分配失败),和具体的回收情况,可以看到内存空间被释放出来了,但却不是全部释放(可以看到原本的空间是3930K,而不是三个数组的3072);
3、 从第二点可以看出,第一次YoungGC只有,有512k的存活,这0.5M的未被回收的内存正好对上了fromspace占满的0.5MB;
是否可以复制一个完整的 JVM,并且在故障转移的情况下只需将负载转移到复制的 JVM 上? 如果是,那我们该怎么做呢? 最佳答案 如果您的应用程序是 Web 应用程序,请阅读“集群”和“负载平衡”。大
我读了下面的话,但我想知道它们之间的区别...... JVM 规范、JVM 实现、JVM 运行时 最佳答案 JVM 规范:描述 JVM 应如何运行的文档。 JVM 实现:基于 JVM 规范的 JVM
我目前有四个不同的 java 应用程序,它们由 .bat 文件启动的 jar 运行,这些文件位于 Windows XP Embedded 开始菜单的 starup 文件夹中。我还启动了 Firefox
有人能给我一些关于强制 64 位 jvm 作为 32 位 jvm 运行的想法吗? 我需要为蓝牙连接编写一个 jse 桌面应用程序。为此,我需要实现 Bluecove jar 。它只有 32 位文件。所
我看到过关于这个问题的多条评论——有人说是,有人说不是,许多答案模棱两可。任何人都可以用更简单的术语描述它所在的位置吗?在一篇文章中,我什至看到有人说它与类加载器加载类的类内存共享相同的内存位置 -
我正在寻找所有可能的 jvm 退出代码的完整列表(不是 java System.exit(x))。我使用搜索引擎唯一能找到的是 SIGTERM 退出代码列表:http://journal.thobe.
为了监视任何正常的 Java 进程 JVM,我们可以使用 Attach API。是否有可用于监控 WebSphere JVM 的 API? 最佳答案 您可以使用 PMI(性能监控基础设施)来监控 JV
这个问题在这里已经有了答案: 8年前关闭。 Possible Duplicate: Java - C-Like Fork? 我想知道如何从 JDK fork 子 JVM,甚至有可能这样做吗? 一些框架
JVM 上的哪些图灵完备语言实现不使用 JVM 堆栈作为调用堆栈? (我问是因为我想在同一个线程中实现 Scala 和另一种语言之间的协程。) 最佳答案 闪蝶 SISC(方案代码的第二解释者) 曾经不
我看到here除了 Java 之外,还有很多语言可以在 JVM 上运行。我对在 JVM 中运行的其他语言的整个概念有些困惑。所以: 为 JVM 使用其他语言有什么优势? 为 JVM 编写语言/编译器需
我已经运行了 straced JVM (OpendJDK 11): strace -e trace=mmap java -Xms8192m Main 输出是: mmap(NULL, 8192, PRO
我已经运行了 straced JVM (OpendJDK 11): strace -e trace=mmap java -Xms8192m Main 输出是: mmap(NULL, 8192, PRO
我编写了一个简单的数独求解器。为了粗略测试性能,我使用简单的 System.currentTimeMillis 调用。 我在文本文件中准备了一组初始数独配置。该程序读取该文件并解决每个数独配置。运行测
JVM 被广泛使用:Scala、Groovy、Jython 等。我听说它被描述为“卓越”、“出色”和“严重低估”。为什么? 更具体地说,是什么让 JVM 独一无二?随着所有资金投入 .NET,或者 C
这个问题在这里已经有了答案: 10年前关闭。 Possible Duplicate: Are there any Java VMs which can save their state to a fi
想象一下 6-7 台服务器的设置都完全相同Java 版本“1.6.0_18”OpenJDK 运行时环境 (IcedTea6 1.8) (fedora-36.b18.fc11-i386)OpenJDK
(如有错误请指正) 我了解到,当您通过发出 java 命令来运行 java 程序时, java MyProg 程序将在新的 JVM 上运行。 什么将程序加载到新的 JVM 中?是生成新线程的 JRE
我们有一个使用 JNI 的桌面应用程序偶尔会导致 JVM 崩溃。幸运的是,JVM 会生成一个 hs_err_pidXXXX.log 文件,这对于调试此类错误非常有用。然而,它似乎总是转到当前工作目录,
我在命令提示符下运行一个程序集 jar 文件并得到下面的异常。并导致终止。 Uncaught error from thread [ccp-akka.persistence.dispatchers.d
一、什么是Java虚拟机 虚拟机:指以软件的方式模拟具有完整硬件系统功能、运行在一个完全隔离环境中的完整计算机系统 ,是物理机的软件实现。常用的虚拟机有VMWare,Visual Box,Java
我是一名优秀的程序员,十分优秀!