学Java三年有余,对自己来说JVM一直以来都是黑匣子,看不懂,摸不透。作为一个有技术情节、略带些许完美主义情节的攻城狮,不了解JVM似乎有时候夜不能寐,总觉得有一个未知的世界自己需要探索。
理论为实践服务,学习JVM不是因为它好玩,其实一点都不好玩,只是因为它有用罢了。实用主义者总比快餐主义让人踏实。 好吧,好奇心害死猫(Curiosity kills the cat),中秋佳节还面对电脑,真是罪过。闲话不多说了,否则显得自己很没礼貌。
学习JVM原理之前,只知道JVM的内存结构有堆、栈之分,堆中存放对象,栈中存放对象的引用。事实上,情况远比上面的一句话复杂的多,当然我仍然没忘记自己是实用主义者,因为我实在想不出有什么理由,去花费大把的时间去和JVM纠缠。
【JVM的内存结构】
简单起见,可以将JVM的内存结构划分为Java堆、虚拟机栈、方法区、本地方法栈、运行时常量池和直接内存。这样的划分不见得合理、或者逻辑清晰,只是为了学习方便而已。如下图所示:
1. Java堆:Heap
是运行时的数据区,主要用来存放Java的对象、数组内容。
2. 虚拟机栈:Virtual Machine Stacks
也可以称之为线程栈,是线程运行的内存区域,存放对象的引用(对象在堆中存放的内存地址),通过对象的引用来访问对象或者数组。
3. 方法区:Method Area
用来存放被虚拟机加载的类的相关信息(如类中的字段、方法的签名等)以及一些其他的元数据。方法区 在JVM规范中被描述为堆(Heap)的一个逻辑组成部分,但是通常称之为非堆(Non-Heap)内存,以表明其和 用来存放对象、数组的堆的不同。在Sun公司提供的HotSpot虚拟机中,方法区使用Java堆(Heap)中的永久代(Permanent Generation)来进行存放。
4. 本地方法栈:Native Method Stacks
用于运行本地方法(Native method)的内存区域,在Sun公司的HotSpot虚拟机中本地方法栈、线程栈共用一块内存区域。
5. 运行时常量池:Runtime Constant Pool
存放运行时的产生的大量常量,如字符串常量,存放在如上所述的方法区。
6. 直接内存:Direct Memory
JDK1.4中加入的NIO(非阻塞I/O)操作类、引入了基于通道(Channel)和缓冲(Buffer)的I/O方式,通过使用Native函数分配堆外内存,然后使用DirectByteBuffer对象来操作这块内存。直接内存和Java堆内存的分配没有任何交集,但是堆内存大小的设置会间接直接内存的可用空间。
【应用实例】
1. 产生Java堆溢出:通过创建大量的对象,并且保持引用来实现。
定义大对象:
class MyObject { byte[] buffer = new byte [1024 * 1024]; }
创建对象,并添加到List集合以避免被垃圾回收器回收:
List<MyObject> bufferList = new ArrayList<MyObject>(); int i = 0; while(true) { System.out.println("第" + (i++ + 1) + "次添加对象."); bufferList.add(new MyObject()); }
设置虚拟机参数:
右键Run As快捷菜单,选择“Run Configurations...”
切换到Arguments选项卡,在VM Arguments文本框输入参数
-Xms20m -Xmx20m
运行程序,抛出Java堆内存溢出异常:
java.lang.OutOfMemoryError: Java heap space
2. 线程栈溢出:通过大量的递归调用来消耗线程栈内存。
定义递归调用函数:
private int i =0; private void recursive() { System.out.println(++ i); recursive(); }
设置VM Arguments参数:
-Xss128k
运行该程序抛出栈溢出异常:
java.lang.StackOverflowError
============================
Ok,JVM内存结构学习到此结束,接下来该看看垃圾回收GC啦!
相关推荐
内容概要:本文详细介绍了LabVIEW控件的设计与实现,尤其是一些由经验丰富的老工程师精心打造的控件。LabVIEW是一款图形化编程语言,广泛应用于数据采集、仪器控制和工业自动化领域。文中通过具体实例展示了如何利用LabVIEW创建美观且功能强大的控件,如滑动条、波形图、金属质感旋钮、动态波形图表以及智能选项卡等。作者强调了LabVIEW控件在灵活性和美观度方面的优势,并分享了许多实用的技术细节和优化方法。 适合人群:具有一定编程基础并希望深入了解LabVIEW控件设计的开发者和技术爱好者。 使用场景及目标:适用于需要进行高效的数据展示和交互设计的应用场景,如工业控制系统、实验室设备操作界面等。目标是帮助用户掌握LabVIEW控件的高级特性,提高开发效率和用户体验。 其他说明:文章不仅提供了具体的代码示例,还探讨了控件美学背后的设计理念和技术实现,鼓励读者探索更多可能性。
Delphi 12.3控件之unidac_10.4.0_d27pro.exe
11.盛趣自闭面(还是自己太菜).txt
58面经面试过程和题目.txt
电大操作系统课后习题解答
人工智能技术与应用演讲【61页PPT】
chromedriver-mac-arm64-135.0.7049.41.zip
内容概要:本文详细介绍了QPSK(四相移键控)调制方法及其在瑞利信道和高斯白噪声信道下的误码率(BER)性能分析。首先展示了QPSK星座图的绘制方法,接着构建了一个简化的QPSK发射机模型,用于将二进制比特流映射到相应的星座点。随后,分别实现了两种信道模型:高斯白噪声信道(AWGN)和瑞利信道,并解释了它们的工作原理以及如何向传输信号添加噪声。文中还提供了详细的误码率测试脚本,通过大量随机比特进行仿真,最终得到了不同信噪比条件下的误码率曲线。此外,作者还讨论了QPSK与其他调制方式如BPSK、16QAM之间的性能差异,强调了频谱效率与抗噪能力之间的权衡关系。 适合人群:对无线通信系统感兴趣的科研人员、研究生以及从事通信工程领域的工程师。 使用场景及目标:①帮助读者理解QPSK的基本原理及其在不同信道环境中的行为特性;②提供实用的Python代码片段,便于快速搭建仿真环境并验证理论结果;③探讨各种调制方式的选择依据,指导实际应用中的优化决策。 其他说明:文中多次提到‘骚操作’,意指一些巧妙但非传统的编程技巧,有助于提高代码执行效率或简化复杂度。同时提醒读者注意仿真过程中可能出现的问题,如
新建 Microsoft Word 文档 (9).docx
计算机科学与技术- 软件开发工具 培训资料
bitcount统计每个元素中设置的位数 B = bitcount(A) Counts the number '1' bits in each element B = bitcount(A, bitValue) "bitValue" = 1 = default = counts the occurance of '1' if bitValue = 0; counts the number '0' The total bits to verify is [8,16,32,or 64] based on the maximal value of A B = bitcount(A, bitValue, maxBits) the total # of bits to examine
MOM生产运营管理平台解决方案【35页PPT】
deli-数码录音电话机-HCD6238(28)P-TSD-使用说明书
Java项目基于ssm框架的课程设计,包含LW+ppt
Delphi 12.3控件之Tsilang 7.5.0.0 D12.7z
ios+UIButton分类+UIButton+UIButton图片文字位置
项目已获导师指导并通过的高分毕业设计项目,可作为课程设计和期末大作业,下载即用无需修改,项目完整确保可以运行。 该系统功能完善、界面美观、操作简单、功能齐全、管理便捷,具有很高的实际应用价值。 项目都经过严格调试,确保可以运行!可以放心下载
Java项目基于ssm框架的课程设计,包含LW+ppt
Delphi 12.3控件之TextEditorPro64.7z
尝试给OpenHarmony4.0增加可以在动态库中使用的日志模块 文章使用的资源,防止gitee资源丢失