研究JVM也有一段时间了,其间也发现了它的很多不足之处,在此一一道来,由于本人对JVM的理解有限,如有错误的地方,还请大家指正;本文不介绍名词性术语和概念性知识,如有不了解的地方可Search Google或者参考一些JVM相关的书籍;

1. 众所周知,所有Java类的元数据在经编译之后,会被保存到Class文件里,个人认为这是一个很扯淡的想法,原因如下:

  • 整个Class文件显得很臃肿,我们在非产品环境中所有的调试信息,如JVM指令与源代码行的对应信息,也会被保存在Class文件里;
  • 降低了获取元数据的速度,比如我们要获取一个包中所有标注了某个Annotation的类(使用Spring MVC时标注了@Controller的Java类),必须加载这个包中所有公共类的Class文件,然后再一一遍历;
  • 无法在不加载Class文件的情况下,获取类型的元数据信息;我们有时候会想得到一个第三方库中的信息,但是不能确定这些包中是否包含了恶意代码,如果加载这些Class文件,势必会执行初始化,这会给恶意代码制造了破坏整个应用程序的机会。[注:这里我说得有问题,事实上是可以做到的]

2. JVM指令有限,虚拟机规范指明在Class文件中每个指令保存为一个字节,也就是说虚拟机中最多允许存在256个指令,这在JVM诞生时,明显足够了;但是计划跟不上变化,随着技术的不断进步,新的特性会越来越多的出现在Java体系中,这些特性需要来自虚拟机层面的支持,因此要求增加更多的虚拟机指令(如JDK1.7为增加对动态语言的支持而新增的invokedynamic),但由于指令空间的局限性导致JVM发展有限。

3. 不合理的范型设计,Java采用了伪范型的方式来支持对集合算法的封装,而在编译之后所有的范型类型参数会被擦除为Object,我无法考证设计者基于什么样的考量而采用这种方式,但从某本书中获得这样的讯息:采用擦除的方式避免了“代码爆炸”的危险;这样的说法明显存在一些问题:

  • 动态生成运行时代码的地方有很多,比如运用得最广的动态代理技术,即在java.lang.reflect.Proxy中,使用了ProxyGenerator.generateProxyClass来为特定接口生成形式为“*$Proxy”的代理类的二进制字节流;
  • 无论运行时生成的代码还是编译时生成的代码,都保存在永久代中(以HotSpot VM为例),而JVM也会在内存不足的情况下对永久代进行回收,所以一般情况下不会出现代码爆炸的危险。

4. 垃圾回收发生的时间问题;我所理解的垃圾回收,应该在三种情况下发生:

  • 内存不足(这里所说的内存不足,都是指分配到某个代上对象的大小超过了该代的容量限制);
  • 代码调用System.gc();
  • 虚拟机根据运行时环境自动触发;

但据我所了解,很多虚拟机只支持前两者,这样虽然减少了GC执行的频率,但是却增多了由于JVM在垃圾回收时停顿所有线程而导致应用程序无响应的危险。

谈谈我印象中的JVM不足之处的更多相关文章

  1. 【原】谈谈对Objective-C中代理模式的误解

    [原]谈谈对Objective-C中代理模式的误解 本文转载请注明出处 —— polobymulberry-博客园 1. 前言 这篇文章主要是对代理模式和委托模式进行了对比,个人认为Objective ...

  2. 谈谈MVC项目中的缓存功能设计的相关问题

    本文收集一些关于项目中为什么需要使用缓存功能,以及怎么使用等,在实际开发中对缓存的设计的考虑 为什么需要讨论缓存呢? 缓存是一个中大型系统所必须考虑的问题.为了避免每次请求都去访问后台的资源(例如数据 ...

  3. java环境中基于jvm的两大语言:scala,groovy

    一.java环境中基于jvm的两大语言:scala,groovy 可以在java项目里混编这两种语言: scala:静态语言,多范式语言,糅合了面向对象.面向过程:可以与java和net互操作:融汇了 ...

  4. 明白生产环境中的jvm参数

    明白生产环境中的jvm参数 写代码的时候,程序写完了,发到线上去运行,跑一段时间后,程序变慢了,cpu负载高了--一堆问题出来了,所以了解一下生产环境的机器上的jvm配置是有必要的.比如说: JDK版 ...

  5. JAVA代码中获取JVM信息

    一.JAVA中获取JVM的信息 原理,利用JavaSDK自带的ManagementFactory类来获取. 二.获取信息 1.获取进程ID @Test public void test1() { Ru ...

  6. Eclipse 中设置JVM 内存

    Eclipse 中设置JVM 内存 今天在eclipse 中测试把文档转换为图片的时候,报出了下面的错误: java.lang.OutOfMemoryError: Java heap space 从上 ...

  7. (转)谈谈RTP传输中的负载类型和时间戳

    原创作品,允许转载,转载时请务必以超链接形式标明文章 原始出处 .作者信息和本声明.否则将追究法律责任.http://ticktick.blog.51cto.com/823160/350142 最近被 ...

  8. 谈谈Vue/React中的虚拟DOM(vDOM)与Key值

    谈谈Vue/React中的虚拟DOM(vDOM)与Key值 一.DocumentFragment 在了解虚拟DOM前,先来了解DOM的一个对象属性--DocumentFragment. 在一次操作中, ...

  9. 零元学Expression Blend 4 - Chapter 7 什麽?影片不再是印象中的方框框!!!看Blend 4如何把影片镶入字里

    原文:零元学Expression Blend 4 - Chapter 7 什麽?影片不再是印象中的方框框!!!看Blend 4如何把影片镶入字里 本章将教大家如何在Blend 4里新增Media El ...

随机推荐

  1. DoModal时带出次级窗口闪现

    最近在做MFC 界面开发. 在一个CDialog窗口DoModal模态显示时, 会将次级窗口带出闪现(比如将一个窗口active, 然后点击我现在程序需要弹框的按钮,弹出弹出正常,但原来active的 ...

  2. 关于HTML Table标签的边框问题总结

    要想td与td间没有距离需要设置如下属性: <table id="table" cellpadding="2" cellspacing="0&q ...

  3. error C2512: “Rectangle”: 没有合适的默认构造函数可用

    解决办法可能为: 1.再构造一个空的显性构造函数:

  4. 安卓中級教程(7):annotation中的 public @interface的用法

    package com.example.ele_me.util; import java.lang.annotation.Retention; import java.lang.annotation. ...

  5. C指针-数组和指针的归一

    int bArr[] = {1,2,3}; int *iarr = bArr; *iarr = 6; printf("%d\n",*iarr); printf("%d\n ...

  6. 数值分析之QR因子分解篇

    在数值线性代数中,QR因子分解的思想比其他所有算法的思想更为重要[1].                                       --Lloyd N. Trefethen & ...

  7. js事件代理(委托)

    JavaScript事件代理(委托)一般用于以下情况: 1. 事件注册在祖先级元素上,代理其子级元素.可以减少事件注册数量,节约内存开销,提高性能. 2. 对js动态添加的子元素可自动绑定事件. 之前 ...

  8. Python开发程序:RPC异步执行命令(RabbitMQ双向通信)

    RPC异步执行命令 需求: 利用RibbitMQ进行数据交互 可以对多台服务器进行操作 执行命令后不等待命令的执行结果,而是直接让输入下一条命令,结果出来后自动打印 实现异步操作 不懂rpc的请移步h ...

  9. 恢复 混淆后的 stacktrace 文件

    ./tools/proguard/bin/retrace.sh /Users/admin/Downloads/ProguardSample/app/build/outputs/mapping/rele ...

  10. Oracle的DML语言必备基础知识

      前提是咱们都已经对常用的数据操纵语言非常熟悉了,对标准SQL: SELECT子句                --指定查询结果集的列 DROM子句                 --指定查询来 ...