在前面三贴中,我提到过
1 Object 要用8byte指针内存
  see (http://topic.csdn.net/u/20081202/14/e93bd51a-a222-4e00-a7a5-5c6f07e7ed52.html)2 Long a = 2l; 
Long b = 2l; 
//结果为ture 
System.out.println(a == b); 
Long c = 128l; 
Long d = 128l; 
//结果为false 
System.out.println(c == d);
  see (http://topic.csdn.net/u/20081119/12/b3c447ef-6665-4225-8d36-60e211663bb3.html)3 JVM会把系统里的字符串常量,缓存到JVM中(在java中如果你定义N多个字符变量,值是一样的,实际在JVM中只有一份)上面3个问题合起来可以说明一个问题:
java对基础数据的cache封装方案是不正确的,应当只能算是曲线救国,解决不了根本问题。
因原很简单:java应当cache 字符,而不是这符串String,
最好的选择是:cache utf-16le(java用的内部字符编码),而java确不是这样做的。
导致的问题:a)符串String 常量是无法确定的,如果在一个系统中使用过多的常量,会让内存涨破。
            b)不能在for等语句中使用String,这样容易让内存out,系统玩完,(往往刚学的新手不知道)。
            c)逼得大家选择Stringbuffer类来操作可变String,很不方便。问题核心提示:java  不cache utf-16le的愿因 是代价比cache String要高。为什么要高呢? 请详细了解 三个问题就可以回答。

解决方案 »

  1.   

    自己占1楼,呵呵,星期六加班,再谈java使用内存的错误设计。
      

  2.   

    lihan6415151528:高手总不能路过,为新手解释一下。呵呵
      

  3.   

    在这个问题上做个广告:我自己做的开源: 
    java,Socket,网络,流,并发,多线程,框架,及例子完整开源代码. 
    http://blog.csdn.net/guishuanglin/archive/2008/12/06/3458689.aspx 
    构建 java多线程,并发设计框架 (一); 
    构建 java多线程,并发设计框架 (二); 
    构建 java多线程,并发设计框架 (三) 
    构建 java多线程,并发设计框架 (四) 
    构建 java多线程,并发设计框架 (五) 
    http://blog.csdn.net/guishuanglin/archive/2008/12/06/3458711.aspx 
    构建 java多线程,并发设计框架 使用列子(一) 
    构建 java多线程,并发设计框架 使用列子(二) 
    构建 java多线程,并发设计框架 使用列子(三) 
    构建 java多线程,并发设计框架 使用列子(四) 
    构建 java多线程,并发设计框架 使用列子(五)
      

  4.   

    搞java也三年了
    觉得java最大的弱点是
    在控制底层硬件上面太弱了
    我也迷惘是不是自己走错方向了
      

  5.   

    理解你的心情,我们公司用java做通信,在数据处理上是没什么大问题,主要是通信方面不好做。
    硬件控制也确实有弱点。对于本楼问题,我测试了cache GBK字符集后,凡字符串都从cache里生成,这样内存只有一份就OK,但是我没想到的是,测试结果
    告诉我,不能这样做。本来想占用少一内存,共享字符集,没想到适得其它反,使用时内存狂增!!
    终于明白 java为什么不cache全部的 utf-16le字符集,而只是几面个英文字符集。
      

  6.   

    从来就不觉得Java做得不烂
    软件慢,JRE各种版本冲突,语法e心
      

  7.   

    看到各位达人的回帖
         是不是JAVA有天生的弊病?
      
      

  8.   

    觉得java最大的弱点是 
    在控制底层硬件上面太弱了 
      

  9.   

    这一次不太同意楼主的看法a)符串String 常量是无法确定的,如果在一个系统中使用过多的常量,会让内存涨破。 
    字符串常量是硬编码到程序里的,目前再大的系统,编译之后生成的class最多几十M了不起了,估计其中的字符串常量也不会超过10%左右,这对一台服务器来说算不了什么。
    b)不能在for等语句中使用String,这样容易让内存out,系统玩完,(往往刚学的新手不知道)。 
    c)逼得大家选择Stringbuffer类来操作可变String,很不方便。 
    我认为这两点都还好,现在的dot net在字符串操处理方式上和java也是类似的
      

  10.   


    在常量上可能象你说的不太明显出现问题,但是问题不会就此消失,因我实际只把他做当做一个设计不当的条件。
    当你在用一些orm工具时,或者要缓存系统基础数据在内存时,就会明显出这设计的问题。而java不能缓存字符集,因为这样就出现更严重的内存问题,实际上从开始这样设计就有问题。
    缓存字符集多爽,可任意组合是任意字符串,系统中也只有一份。
      

  11.   

    String作为基础的类,弄成final也是没办法的事情,一是出于效率,二是出于安全性。
                
    b)不能在for等语句中使用String,这样容易让内存out,系统玩完,(往往刚学的新手不知道)。 
    c)逼得大家选择Stringbuffer类来操作可变String,很不方便。

    循环里面用String也是可以的,JAVA的GCJVM会自己调,但有必要的话也可以在程序里手动调GC回收内存。JAVA底层控制弱这没办法,毕竟隔了层JVM,上JNI调C吧。
    感觉LZ看问题实在是很偏颇啊,JAVA本身的优势在于稳定性(靠JVM),简单易学(没有指针这些容易让初学者绕晕脑袋的东西)和丰富的资源(开源)。事实证明,JAVA是成功的,1.)JVM实现了跨平台的同时也保证了系统的安全性,你代码漏洞再大也顶多把JVM弄崩溃,OS还是好好的,为此,付出一点性能代价是可以接受的。2.)简单易学意味着能快速的培养大批coder,意味着使用JAVA的公司能用相对便宜的价格招到开发人员,这意味着开发成本降低。
      

  12.   

    "JAVA的公司能用相对便宜的价格招到开发人员,这意味着开发成本降低"楼上,这个好象对过来了吧,同时java也比.net等难学多了。乱七八糟框架一堆。
    价格上面,是不是反过来了啊?哈哈
      

  13.   

    只是目前没有比java更好的选择,但是java总不能吃老本,
    如果这样,要是有更好的选择,java玩完的日子不远了。
      

  14.   


    扯淡自重,讨论问题对事不对人.
    即使是在Sun内部,关于底层设计方案相信也很多,不过Sun以自己的理由进行了取舍而已.
    不同意见很正常,随便说嘛喵~```
      

  15.   

    相比较java还是很简单的,虽然不像C/C++那样有艺术性,
      

  16.   

    老是在这里说些JAVA不好的话,哎,应该封号!!
      

  17.   

    楼主觉得Java对底层控制的不好的话  把自己的青春贡献给JVM吧  保证你不后悔
      

  18.   

    没怎么看。树业有专功。本就没有完美的东西。
    说java烂,有觉得有点过了。
      

  19.   

    你觉得 Java“烂”是因为你选错了开发语言和开发平台,不同的语言和平台适合不同的需求,语言无所谓烂与不烂,在一个平台上开发出的应用才有烂与不烂之分!
      

  20.   

    没反,就是因为框架多,学了一两个框架就能开发了。这样的程序员目前大把,工资真的很低。当然,这是相对于C来说的。.net的话,那东西比java还简单,所以做.net的薪水普遍不高
      

  21.   


    UTF-16LE 只是一种编码格式,并不是所谓的字符集,而 Unicode 才是字符集,
    Java 中将 U+0000~U+00FF 的字符进行了缓存。Java语言规范指出:特定的基本类型一定得被装箱成包装对象。这些对象会被
    高速缓存以重复使用,并且会被当作一般使用的对象。这些特殊的值是:boolean: true、false
    byte: 所有的值
    short、int和long: -128~127
    char: \u0000~\u007F
    float和double:不会被缓存 
      

  22.   

    说错了,是 U+0000~U+007F 的字符。
      

  23.   

    说穿了,java只能缓存部分字符,而不能缓存字符集,我经过测试后发现的。
    1,Stirng里使用的是 char[]数组,char 2字节。
    2,cache字符集,对sun来说是件容易的事,但是字符串的设计让java很为难.
    3,一个对象的引用在java里占:8byte.问题出来了:
      假设 String = "反对法国,抵制法货" 单单String 中的 char[]占 18字节.
      如果改成cache 引用:"反对法国,抵制法货" 占:72字节 !!。
    不难看出,java不能直接改 String 的设计,可能最先设计JVM时考虑不周,或者其它原因。
    不能修改 String的设计,java只能选择 部分引用常的字符,来解决速度,与时间的问题。结论:java在目前的设计上不能用cache全部字符的方式,来加快java的速度,与节省内存。
    但是,如果要从根本上解决问题,必须从JVM上入手。打破java使用内存空间以 8为倍数的设计方式。
      

  24.   

    上面有人说要封号,我觉得出发点不正确:
    使用java的人,应当更要了解java的 不足,而不是一知半解。
    这样才能做出好的软件。这也是设计一个java系统的必须要的知识。
      

  25.   

    充分说明你根本不了解JAVA的设计思想。
    2 Long a = 2l; 
    Long b = 2l; 
    //结果为ture 
    System.out.println(a == b); 
    Long c = 128l; 
    Long d = 128l; 
    //结果为false 
    System.out.println(c == d); 就拿这个问题来说。Long对象可能的值有多少?那是一个天文数字,但为什么只cache了 -128到127?
    int 值有2的32次方,为什么只调用ild_0到ild_9的10个直接指令?其实这正是JAVA实现时CACHE原则的精妙之处。
    个C一个论坛,如果开上三年,贴子可能上千万,但常来论坛的人最常看的是哪些?
    最近三天的,所以只要把最近三天的贴子放到内存中,这个CACHE原则就是非常正确的思想。
    CACHE那些98%的人去浏览的2%的数据,这是UOP思想的正确应用。因为JVM不可能CACHE一个天文数字的可能,
    那么CACHE最常用来的命中率最高的数据就是一个正确的设计思想。整数指令不仅仅是数学运算,因为大量的数学运算CACHE根本不想作用,而更多的情况是牧举,标记,信号量等。
    在这种情况下,根据一个正常的编程人员的思维,为0-9设计直接指令可以解决大多数情况,为Long cache 256个对象也可以解决大多数情况。
    如果一个编程人员在使用两个互斥标记时不是用0和1,而是用994和995,肯定没有问题,但作为设计JVM的人在CACHE时要考虑有人不用0和1而用994和995,那这个人的脑子就和用994和995的程序员一样不正常。CACHE原则本身就是根据大多数人的习惯来设计的。
      

  26.   

    你说的导致的 问题更是搞笑。
    a)符串String 常量是无法确定的,如果在一个系统中使用过多的常量,会让内存涨破。 
                b)不能在for等语句中使用String,这样容易让内存out,系统玩完,(往往刚学的新手不知道)。 
                c)逼得大家选择Stringbuffer类来操作可变String,很不方便。 这三个问题更说明你不懂JVM的实现。字符串常量池在运行时被映射到方法帧中。如果一个方法帧内的字符串常量池太会溢出。那以前的任何语言一定溢出,因为之前的任何语言汇编成机器码的时候,所以字符串常量都会在方法调用栈中入口点上面的临时表中,而且相同内容的字符串分别保存。占用的空间比JVM的常量池更大,因为JVM的常量池是把内容相同的合并了。JVM这种设计不但不会降低性能反而提高了性能,因为JAVA编译器比传统编译器更聪明。第二个问题同样道理。第三个问题更是因为你的无知而引起的。设计模式的作用如果用过程语法分析,就象分析一个国家的宏观经济时说街上张三麻子亏了一样。按你说我COPY一个文件,要从用户模式到内核模式的7次切换,要从换到用户模式读写缓冲到内核模式的读写缓冲的4次COPY。这样作业系统最底层的设计也是很烂?大量浪费空间和性能?当你自己不懂一种设计的核心思想时你没有资格说什么烂一,不客气地说实现JVM的人比你聪明多了,他们多少年来也在不断优化,你说的那些问题根本不是问题,仅仅是因为你自己不懂而已。一个小学生,他肯定说数学体系很烂,因为他认为整数多方便啊,加减乘除很快啊,还要弄个小数和,虚数之类的东西,浪费计算时间。
      

  27.   

    你说的导致的 问题更是搞笑。
    a)符串String 常量是无法确定的,如果在一个系统中使用过多的常量,会让内存涨破。 
                b)不能在for等语句中使用String,这样容易让内存out,系统玩完,(往往刚学的新手不知道)。 
                c)逼得大家选择Stringbuffer类来操作可变String,很不方便。 这三个问题更说明你不懂JVM的实现。字符串常量池在运行时被映射到方法帧中。如果一个方法帧内的字符串常量池太会溢出。那以前的任何语言一定溢出,因为之前的任何语言汇编成机器码的时候,所以字符串常量都会在方法调用栈中入口点上面的临时表中,而且相同内容的字符串分别保存。占用的空间比JVM的常量池更大,因为JVM的常量池是把内容相同的合并了。JVM这种设计不但不会降低性能反而提高了性能,因为JAVA编译器比传统编译器更聪明。第二个问题同样道理。第三个问题更是因为你的无知而引起的。设计模式的作用如果用过程语法分析,就象分析一个国家的宏观经济时说街上张三麻子亏了一样。按你说我COPY一个文件,要从用户模式到内核模式的7次切换,要从换到用户模式读写缓冲到内核模式的读写缓冲的4次COPY。这样作业系统最底层的设计也是很烂?大量浪费空间和性能?当你自己不懂一种设计的核心思想时你没有资格说什么烂一,不客气地说实现JVM的人比你聪明多了,他们多少年来也在不断优化,你说的那些问题根本不是问题,仅仅是因为你自己不懂而已。一个小学生,他肯定说数学体系很烂,因为他认为整数多方便啊,加减乘除很快啊,还要弄个小数和,虚数之类的东西,浪费计算时间。
      

  28.   


    别拿着西瓜说东瓜,你回答的这些东西,都没看清题一样,如果面试的话 0分。
    随便足几个出来:
    "JVM这种设计不但不会降低性能反而提高了性能,因为JAVA编译器比传统编译器更聪明。"这个要你提醒,楼上的都知道
    其它的别人会看,不用我说。
      

  29.   

    给axman建议:你不想进步了解,或者就算你了解更深,而不告诉大家,不与其它人分享,有用吗?
    不要泛泛而谈,多拿出点实际的东西出来,多拿点数据证明。
      

  30.   

    有点意思,标记一下
    各位继续,我对axman很景仰,呵呵从这么一点(也许是有不适用的地方)说java就烂,有点过了,瑕不掩瑜阿!
      

  31.   

    术业有专攻
    Java 本身优势在于Java EE
    不过也还是希望 Java 把存在的一些问题好好改进