研究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. hibernate 异常:could not execute statement

    错误信息: JDBC exception on Hibernate data access: SQLException for SQL [n/a]; SQL state [72000]; error ...

  2. 安卓中級教程(8):pathbutton中的animation.java研究(1)

    src/geniuz/myPathbutton/myAnimations.java package geniuz.myPathbutton; import java.util.ArrayList; i ...

  3. IOS基础学习-2: UIButton

    IOS基础学习-2: UIButton   UIButton是一个标准的UIControl控件,UIKit提供了一组控件:UISwitch开关.UIButton按钮.UISegmentedContro ...

  4. java 字符流与字节流互转

    package test; import java.io.BufferedReader; import java.io.ByteArrayInputStream; import java.io.IOE ...

  5. jQuery 实时监听<input>输入值的变化

    这方法比 on('keydown') 更实时 <input type='text' id='input1'/>$(document).ready(function(){ $('#input ...

  6. mysql slow query---pt-query-digest----db structure consistency,monitor table records before and after transaction.

    将数据库脚本纳入版本管理是很必要的,尤其对于需要在客户那里部署升级的系统. 对于Python Django等框架,由于数据库是通过Model生成的,因此框架本身包括数据库升级工具,并通过代码版本间接管 ...

  7. linux系统文件权限

    Linux文件权限详解 文件和目录权限概述 在linux中的每一个文件或目录都包含有访问权限,这些访问权限决定了谁能访问和如何访问这些文件和目录.通过设定权限可以从以下三种访问方式限制访问权限:只允许 ...

  8. 针对功能权限(url访问)如何避免越权访问

    你可以用request获得之前的页面路径:Request.getHeader("Referer");然后你可以判断一下,这个是字符串类型的. 如果是需要登录的,你可以从sessio ...

  9. wamp下多域名配置问题

    1.找到wamp安装目录的apache安装目录 找到 httpd.conf文件 例如我安装的目录为 E:\wamp\bin\apache\apache2.2.8\conf\httpd.conf 也可以 ...

  10. Big Data

    Hadoop安装教程_伪分布式配置_CentOS6.4/Hadoop2.6.0 http://dblab.xmu.edu.cn/blog/install-hadoop-in-centos/ Spark ...