`

从jvm的自愈说起-设计JVM的疯子和写java程序的疯子

阅读更多

 

http://it.deepinmind.com/jvm/2014/12/15/self-healing-jvm.html这里说了一个观点,叫做 JVM的自愈能力,就是说JVM在遇到问题时会自己发现问题解决问题,举例如下:

 

 

package eu.plumbr.test;

public class HealMe {
  private static final int SIZE = (int) (Runtime.getRuntime().maxMemory() * 0.6);

  public static void main(String[] args) throws Exception {
    for (int i = 0; i < 1000; i++) {
      allocateMemory(i);
    }
  }

  private static void allocateMemory(int i) {
    try {
      {
        byte[] bytes = new byte[SIZE];
        System.out.println(bytes.length);
      }

      byte[] moreBytes = new byte[SIZE];
      System.out.println(moreBytes.length);

      System.out.println("I allocated memory successfully " + i);

    } catch (OutOfMemoryError e) {
      System.out.println("I failed to allocate memory " + i);
    }
  }
}

按照道理,总是这样分配内存一定会内存不足,报OOM异常的,但是,文章提到,在JVM8中,在运行了256次allocateMemory()方法2之后,C1编译器会将这个方法进行3级编译。它会一次性查看整个方法,因此它能推断出后面不会再用到bytes变量,可以对它进行GC。所以才会触发垃圾回收,因此程序才能奇迹般地自愈。

 

我想说的是:设计这样JVM的人和在真正产品实现里写这样代码的人都是疯子。


前者是越俎代庖,非要管人家上层程序员的事:你就是一个VM,一个底层,上层要你干啥你就干啥,自作主张的给人家优化---就行秘书自作主张的改领导的批示一样。结果又两个,一是改了不大紧要的地方,可有可无,真正重要的地方改不了;二是改了让人家的业务过程变了,与预期不符。是在可笑之极。

---一句话:谁的逻辑除了bug谁负责,这还需要解释吗?家里养的猫不抓老鼠,就指望养的牛抓老鼠?

后者是疯子:你写个代码出这样的bug,自己找根绳去吧!有了bug自己不负责,指望jvm来怎么治愈自己,说实在的也就是写个程序玩玩吧,真正写商业程序,死都不知道死到哪儿去。

 

 

 

 

 

2
10
分享到:
评论
11 楼 windshome 2014-12-19  
其实这属于开发方法论,在设计时需要仔细设计的一点。

完整系统切割为多个子系统(定义各子系统的职责和通信、依赖关系、层次关系),一个子系统切割为模块(模块职责和通信、依赖关系),一个模块划分为多个部件(部件职责和通信、依赖关系)。

从另外一个角度,还可以划分为框架(例如IoC框架)、基础设施(例如JVM,或者数据库连接池、界面组件)处理单元(业务处理),各部分在整体系统中,各有各的职责,做好自己本分,按照设计做好通信和依赖的接口,系统基本就能很好的连接在一起运转,不需要哪个部分非要管别的部分的事情。也不要指望自己的事情由其他模块代替来做。哪个部分出了问题,哪个部分负责。


还有一种情况,就是负责某一部分的人是懒虫,巴不得其它部分能替自己做一些,于是臃肿的框架出现了,复杂的底层设施日趋复杂,业务除了所谓的CRUD就没啥东西了,也号称自己业务逻辑....短期看,项目型开发来看,还挺快,但长期来看,从开发产品的角度看,损害了设计,损害了系统设计开发中人的行为模式。

10 楼 windshome 2014-12-18  
ljbupc 写道
windshome 写道
其实这是自作聪明。呵呵。

一个平台,忠实的做上层交待的事情就可以了,水平高的人做出水平高且好用的东西,水平差的人做的东西就是总是出bug。平台没有必要管这个。





理解你的意思,但事实上,水平高的没几个,水平差的很多(包括我)。

jrokit 应该很早就加入了这个东东的,而且我应该遇到过这个东西引起的倒霉事。
一个批量程序,用jrokit1.6运行,前几百条记录执行的计算结果是正确的,后面的结果就变成0了;
换成sun jdk1.6就没有该问题。

后来换sun jdk了,没有时间去仔细研究,不过从现象来看,99%的可能性是jrokit自己帮我“优化”程序了。


水平什么样都没有关系,自己出问题了自己负责就行。
9 楼 ljbupc 2014-12-18  
我勒过去。。。。
刚去测验了一下。。
这程序在jrokit 1.6中一开始就是分配成功的。。。。
8 楼 ljbupc 2014-12-18  
windshome 写道
其实这是自作聪明。呵呵。

一个平台,忠实的做上层交待的事情就可以了,水平高的人做出水平高且好用的东西,水平差的人做的东西就是总是出bug。平台没有必要管这个。





理解你的意思,但事实上,水平高的没几个,水平差的很多(包括我)。

jrokit 应该很早就加入了这个东东的,而且我应该遇到过这个东西引起的倒霉事。
一个批量程序,用jrokit1.6运行,前几百条记录执行的计算结果是正确的,后面的结果就变成0了;
换成sun jdk1.6就没有该问题。

后来换sun jdk了,没有时间去仔细研究,不过从现象来看,99%的可能性是jrokit自己帮我“优化”程序了。
7 楼 mike.liu 2014-12-18  
其实说得也有一定道理。
职责不分,功能太臃肿,是导致Android用2倍内存也拼不过iPhone顺畅的原因之一。
在iOS里面,内存分配和释放,框架做一部分,程序员负责一部分,各自做好自己的事情,没有GC。JVM帮助程序员管理了所有内存分配和释放的事情,是必须付出代价的。高内存占用和间歇性的卡顿,就是代价之一。
系统设计的策略就是取舍,保守未必是坏事,激进未必是好事,仔细权衡之后,看运气吧。
6 楼 windshome 2014-12-18  
其实这是自作聪明。呵呵。

一个平台,忠实的做上层交待的事情就可以了,水平高的人做出水平高且好用的东西,水平差的人做的东西就是总是出bug。平台没有必要管这个。



5 楼 ljbupc 2014-12-18  
windshome 写道
ljbupc 写道
其实博主不必要这么激动,
JVM也是一个虚拟机,这么设计么就是为了避免一两个恶意程序让整个虚拟机宕机;
JVM为了不让自己宕机,找到一些没有再使用过的东西快速回收掉。
其实linux也有类似的设计,当需要内存而没有内存的时候,内核还会kill掉某些进程。

不过这样的设计就要求较高,回收资源可以,但不能乱去优化,改变应用程序的处理逻辑。那样就容易出现优化错误出现一些奇奇怪怪的bug。


呵呵,我只是说有些职责不明,业务端设计实现存在bug,导致JVM宕机,是人家的事情,和你jvm有什么关系?jvm只是一个支撑业务的基础设施,上层使用不当,出现问题就应该负相应的责任,想办法去处理。


其实这也是一个卖点,他多了一层保护。
复杂程序都会有bug的,他说他能减少bug带来的影响,相信很多公司都会觉得好(毕竟大部分写程序的人水平不一定有多高),当然前提是成熟。

运行时编译优化是为了提高代码运行效率,干了内存泄露回收的事只是个附带。
4 楼 windshome 2014-12-18  
ljbupc 写道
其实博主不必要这么激动,
JVM也是一个虚拟机,这么设计么就是为了避免一两个恶意程序让整个虚拟机宕机;
JVM为了不让自己宕机,找到一些没有再使用过的东西快速回收掉。
其实linux也有类似的设计,当需要内存而没有内存的时候,内核还会kill掉某些进程。

不过这样的设计就要求较高,回收资源可以,但不能乱去优化,改变应用程序的处理逻辑。那样就容易出现优化错误出现一些奇奇怪怪的bug。


呵呵,我只是说有些职责不明,业务端设计实现存在bug,导致JVM宕机,是人家的事情,和你jvm有什么关系?jvm只是一个支撑业务的基础设施,上层使用不当,出现问题就应该负相应的责任,想办法去处理。
3 楼 wu.sheng 2014-12-18  
JVM的优化目的,应该是减少无用的垃圾变量的声明和使用,局部变量的尽快回收,只是刚巧达到了这么一个效果而已。
2 楼 fxldiezh 2014-12-18  
JVM越来越傻瓜化了
1 楼 ljbupc 2014-12-18  
其实博主不必要这么激动,
JVM也是一个虚拟机,这么设计么就是为了避免一两个恶意程序让整个虚拟机宕机;
JVM为了不让自己宕机,找到一些没有再使用过的东西快速回收掉。
其实linux也有类似的设计,当需要内存而没有内存的时候,内核还会kill掉某些进程。

不过这样的设计就要求较高,回收资源可以,但不能乱去优化,改变应用程序的处理逻辑。那样就容易出现优化错误出现一些奇奇怪怪的bug。

相关推荐

Global site tag (gtag.js) - Google Analytics