刚才写程序的时候去抓网页,而网页里html的string往往都很大.而且我用得还是多线程,多个网页一起抓,所以很容易产生heap stack 溢出我原先的多线程采用的是生产者-消费者模式放在一个容量为2的Runnable数组里.现在还是想用生产者-消费者模式
但是不想根据数组的当前容量来判断是否要再执行下一个线程了,
想根据当前heap stack 占用的内存来判断
如果占用的内存除以总的heap stack内存 > 70%,则阻塞
如果<=70%,则继续执行下一个线程现在首先碰到的问题是,不知道如何获取总共的heap stack是多少M?以及当前java程序占了heap stack多少M?
请问如何解决这个问题?

解决方案 »

  1.   

    代码如下: Runtime rt = Runtime.getRuntime();
    long freeMemory = rt.freeMemory();
    System.out.println("当前 Java 虚拟机中的空闲内存量:" + freeMemory + " 字节");
      

  2.   

    空闲内存:
    Runtime.getRuntime().freeMemory()
    总内存:
    Runtime.getRuntime().totalMemory()
    最大内存:
    Runtime.getRuntime().maxMemory()
    已占用的内存:
    Runtime.getRuntime().totalMemory() - Runtime.getRuntime().freeMemory()
      

  3.   

    抓个网页还不至于导致溢出吧。
    加大内存试一试
    取当前java程序的内存占用是什么意思?java中的内存管理不交给开发人员所以相应的接口也就是少
    笨办法前后相减计算下。
    http://blog.csdn.net/sunyujia/archive/2008/04/21/2313318.aspx
      

  4.   

    又有个疑问啊,我现在的情况是:空闲内存: 
    Runtime.getRuntime().freeMemory() 
    总内存: 
    Runtime.getRuntime().totalMemory() 
    最大内存: 
    Runtime.getRuntime().maxMemory() 
    已占用的内存: 
    Runtime.getRuntime().totalMemory() - Runtime.getRuntime().freeMemory() 运行上面四句得到:空闲内存:4M
    总内存:5M
    最大内存:66M
    已占用的内存:0M我已经把eclipse目录下的eclipse.ini文件中各种关于内存的设置都设置成了512M
    如下:
    -showsplash
    com.genuitec.myeclipse.product
    --launcher.XXMaxPermSize
    512m
    -vmargs
    -Xms512m
    -Xmx512m
    -Dosgi.splashLocation=C:\eclipse3.3\links\MyEclipse 6.0\eclipse\MyEclipseSplash.bmp
    -Duser.language=en 
    -XX:PermSize=512M 
    -XX:MaxPermSize=512M为什么总内存还是只有66M呢,这个怎么设置的?
      

  5.   

    一定是有逻辑上的问题,开两个就挂了,那就没法用java写程序了是不是我最多开100个 还是同时操作数据库呢,都不溢出。
      

  6.   

    可能是因为我最大内存:66M 
    我电脑内存2g,就是不知道怎么把最大java内存调高点
      

  7.   

    我想,楼主所产生的问题,应该不是因为String内容过大而产生的。
    一个HTML页面,占用不了多大的内存的,
    我觉得,关键问题是,楼主所抓下来的也面,没有进行及时的释放。我不太清楚,楼主的多现成具体的实现形式,如果,要是,我来实现,生产者和消费者线程之间,会有一个数据队列。
    生产者将抓下来的数据存到队列里面,消费者线程从队列里面取数据,进行处理。
    那么,把队列的最大值设置的小一些,就可以解决堆栈溢出的问题了。(因为当队列长度达到最大值的时候,生产者线程会被阻塞)如果中间没有数据队列,楼主检查一下生产者和消费者的代码。
    生产者的代码中,有没有无限存放抓取页面信息的集合类,如果有,尽量替换成带有峰值的阻塞队列。
    消费者的代码中,在处理完生产者的数据后,这些对象,是否被其他的对象(尤其是集合对象)所引用,
        如果有,请想办法去掉这些引用,或者将这些信息保存到文件中去。(节省引用某种意义上就是节省内存容量)
      

  8.   

    嗯,说的没错,我也考虑过这个问题,但是要改代码得费不少周折,
    现在看到java最大内存才66M
    我想试着调到512M,反正我内存也2G,
    要是调到512M都不行,我就准备按你的这个方法做了但是现在不知道在哪里可以把java最大内存调到512M?
      

  9.   

    如果用Java或Javaw命令去运行,可以通过命令行参数设置最大内存。如果是在Eclipse中直接运行,则可采用如下方法:在你的包含main方法的那个类的源代码上,点右键。
    Run As -> Open Run Dialog
    在右边的选项卡中,找到 Arguments,在下边的VM arguments中填入-Xmx512m,点右下角的 Run
      

  10.   

    一旦设置一次之后,以后直接运行即可。会自动保留你之前所设置的运行参数的。这是在我的机器上的运行结果:最大可用内存:508 M产生该输出的代码是:
    System.out.println("最大可用内存:" + rt.maxMemory()/1024/1024 + " M");
      

  11.   


    你之前所做的这个是Eclipse这个IDE本身的内存设置。
    Eclipse运行你自己所写的程序时将启动一个新的JVM,所以应该在Run Dialog中配置运行参数。
      

  12.   

    嗯,不错,我试过了,确实是可以的,
    但是好像没运行一个java文件都要这么设置一遍,能不能设置成我运行所有java都自动填入"-Xmx512m"呢?
      

  13.   

    好象是不行,局我所知,好象可以设置某个项目的-Xmx512m参数,但是,所有项目的-Xmx512m参数,我就不知道怎么改了。
    毕竟,这个参数,是运行JVM的时候添加的。
      

  14.   

    顺便问一下,为什么我回复的时候不能插入图片呢,怎么才能在回复中添加一张图片呢?
    如何将一张图片上传给csdn呢?
      

  15.   

    在回复时点工具栏上的“插入图片”的按钮可添加图片。
    其必须指定以http://开始的URL,所以之前得把本机的图片进行上传。
    (以上内容想必楼主已经知道了)至于图片的上传可以通过博客的发布页面完成。
    如下图,点图中红圈所指定的链接可以进行博客的发布页面,该页面具备独立的图片上传的功能:可以只上传图片而不必发博。
    操作过程非常简单,楼主过去之后一看便知。
      

  16.   

    一般得把图片发到csdn的空间或博客里面,得到它的url地址,不然别的网站好多都不能显示的。
      

  17.   

    打开任务管理器看看不就得了..什么大程序也不开..看看哪个占得内存最多..哪个在消耗CPU就知道你的程序是那个么.
      

  18.   

    任务管理器看不出什么,又不是你用多少jvm再向os申请多少.
      

  19.   

    我觉得jconsole好像可以吧