• ベストアンサー

Javaでメモリ不足を引き起こす方法

Javaを使って、システムのメモリ不足を引き起こす方法を考えています。 (動作検証のためで、悪いことを考えているわけではありません^^;) 下記のプログラムでメモリを大量に消費するかなと思ったのですが、 Linux上のvmstatやtopなどで確認してもそれほど変化がありません。 while (true) { Integer[] ii = new Integer[100]; for (int i = 0; i < 100; i++) { ii[i] = new Integer(i); } } Javaの1プロセスが使えるメモリの上限があるので、メモリを食いつぶすプロセスを 大量に実行すれば良いと考えているのですが、メモリを食いつぶす方法が分かりません。 よろしくお願いいたします。

  • Java
  • 回答数2
  • ありがとう数2

質問者が選んだベストアンサー

  • ベストアンサー
noname#94983
noname#94983
回答No.1

このプログラムだと、whileで繰り返してInteger[] ii = new Integer[100];すると、その前の繰り返しでiiに設定されていた配列は、どこからも参照されなくなるため、ガベージコレクションの対象となる。このため、常に、現在使っているiiに設定されているInteger配列以外は、必要に応じてガベージコレクションで消去されるため、永遠にメモリ不足にはならない。 メモリ不足を起こすには、生成されたオブジェクトがすべて参照された状態である必要がある。試してないが、例えば、ArrayListなどに次々とaddしていくのを繰り返したりすれば、メモリが消費される一方になるんじゃないだろうか。

oubokun
質問者

お礼

logger_manさん、 ArrayListでaddし続けるとメモリが消費され続けました。 ありがとうございました。

その他の回答 (1)

  • e00083
  • ベストアンサー率31% (25/80)
回答No.2

私の場合は、クラスを多数作りすぎて、OutOfMemoryErrorを投げられたため、try catchで、スローされるとそこで、インスタンス化を止めるプログラムを作ったことがありますね。 大量のクラスをインスタンス化すると、イヤでも出会えますよ。 ちなみに、OSの動作等は問題は起こりませんでした。

oubokun
質問者

お礼

e00083さん、 ArrayListでうまくいきましたが、try catchは参考になりました。 catchでスリープすると、良い感じの動作になりました。 ありがとうございました。 ちなみに10数個プロセスを実行すると、スワップ領域も食いつくした後、Linuxが強制的に再起動してしまいました。

関連するQ&A

  • java.util.Comparatorのcompareメソッドの振る舞いについて

    はじめまして。 質問をさせていただきます。 以下のソースで、 =============================================================== import java.util.Comparator; import java.util.TreeSet; import java.util.Iterator; final class Demo { public static void main(String[] args) { TreeSet<Integer> set = new TreeSet<Integer>(new Comparator<Integer>() { public int compare(Integer i,Integer j) { int result = i%2 - j%2; if(result==0) { result = i-j; } return result; } }); for(int i=0;i<10;i++) { set.add(10-i); } Iterator<Integer> it = set.iterator(); while(it.hasNext()) { System.out.println((Integer)it.next()); } } } ================================================================ 実行結果 ================================================================ 2 4 6 8 10 1 3 5 7 9 ================================================================ 偶数が最初に昇順で出力され、奇数が後から昇順で出力されている のですが、なぜこのような実行結果になるのかがわかりません。 どうかご教授お願いします。

    • ベストアンサー
    • Java
  • javaで配列の格納をしたいです。

    配列の格納がうまくいきません。 javaについて質問させて頂きます。 ユーザーが数字を入力し配列 atr[ i ]に格納され 配列 v[ i ] に v[ 0 ] = count ... v[ 143 ] = count ... v[ 144 ] = count - 1 ... v[ 287 ] = count - 1 ... ... v[ count-288 ] = 2 ... v[ count-145 ] = 2 ... v[ count-144 ] = 1 ... v[ count-1 ] = 1 と、格納されるようなプログラムを作っています。 for文で作ろうと考えたのですが count, count-1 , ... 3, 2, 1と値を入れようと思いましたがうまくコンパイルが通りませんでした。 エラーは以下になります。 a.java:48: シンボルを見つけられません。 シンボル: メソッド readLine(int) 場所 : java.io.BufferedReader の クラス value = br_v.readLine(atr[i]); もし宜しければアドバイスやご指摘を頂けませんでしょうか。 説明も拙い部分がありますが宜しければお願いします。 import java.io.*; import java.util.Arrays; class a { public static void main(String[] args) throws IOException { int atr[]; atr = new int[25]; int count = 0; BufferedReader br = new BufferedReader(new InputStreamReader(System.in)); while(true){ //絶対に通る String str = br.readLine(); int res = Integer.parseInt(str); if(res == 0){ break; } else{ atr[count] = res; } count++; } for(int i=0; i<count; i++){ System.out.println(atr[i] + "が、選択されました。"); } int v[] = new int[25*144]; String value; try{ BufferedReader br_v = new BufferedReader(new InputStreamReader(System.in)); for(int i=count; i<count; i--){ value = br_v.readLine(atr[i]); v[i] = Integer.parseInt(value); } } catch(IOException e){ System.out.println("エラーです。"); } } }

  • Javaのメモリ・リークについて

    Javaのメモリ・リークについて 以下のコードはスレッド内で、無限ループをしています。 コンストラクタで呼び出し、ずっとこのままにしておいてもフリーズするか否かが知りたいです。 (jconsole.jarというツールがありますが、まだ理解に至っておりません。) ご存知の方がおられましたら教えてください。 よろしくお願いいたします。 import java.awt.event.ActionEvent; import java.awt.event.ActionListener; import javax.swing.JButton; import javax.swing.JFrame; public class ActioneventRoopTest extends JFrame implements Runnable, ActionListener { JButton start = new JButton(); JButton change = new JButton("切り替え"); Boolean flag = true; public static void main(String[] args) { new ActioneventRoopTest(); } public ActioneventRoopTest() { change.addActionListener(this); start.addActionListener(this); this.add(change); this.pack(); this.setVisible(true); Thread thread = new Thread(this); thread.start(); } public void actionPerformed(ActionEvent e) { if (e.getSource() == change) { if (flag) { flag = false; } else if (!flag) { flag = true; } } } public void run() { while (true) { while (flag) { System.out.println("リンゴ"); } while (!flag) { System.out.println("ミカン"); } } } }

    • ベストアンサー
    • Java
  • Java Applet での虫食い算での質問

    初めて利用させていただきます。 今、課題で虫食い算のプログラムを作成しているのですが、うまく動作してくれません。 もしよろしければご指摘をしてもらえればと思い書き込みのほうをさせていただきます。 import java.awt.BorderLayout; import java.awt.Button; import java.awt.Color; import java.awt.Event; import java.awt.Font; import java.awt.Graphics; import java.awt.Panel; import java.applet.Applet; public class musikuizan_1 extends Applet { int A, B; int cnt; int sub(int n,int m) { int i; for (i=1; i<m; i++) n /= 10; return n % 10; } void puzzle() { int a; int b; int c; int d; int e; for (a=1; a<=99; a++) { for (b=1; b<=99; b++) { c = a * (b % 10); d = a * (b / 10); e = a * b; if (c>=100 && c<=999 && d>=10 && d<=99 && e>=100 && e<=999) /*桁数調整*/ { if (sub(b,1)==3 && sub(c,2)==1 && sub(d,2)==8) /*穴埋めされてある部分の数*/ { A = a; B = b; cnt++; } } } } } public void init() { setBackground(new Color(150,180,200)); setLayout(new BorderLayout()); Panel psouth = new Panel(); psouth.add(new Button("実行")); add("South", psouth); } public void paint(Graphics g) { int i, c, d, e; for (i=1; i<=2; i++) { g.drawRect(97-i*20, 5,16,16); g.drawRect(97-i*20,25,16,16); g.drawRect(77-i*20,65,16,16); } for (i=1; i<=3; i++) { g.drawRect(97-i*20,45,16,16); g.drawRect(97-i*20,85,16,16); } for (i=1; i<=4; i++) g.drawLine(30,43,100,43); g.drawLine(30,83,100,83); g.setFont(new Font("Helvetica",Font.BOLD,18)); g.drawString("x",40, 40); if (A == 0) { g.drawString("3",60, 40); g.drawString("1",60, 60); g.drawString("8",60, 80); g.setFont(new Font("Helvetica",Font.PLAIN,12)); g.drawString("cnt = ",30,115); } else { c = A * (B % 10); d = A * (B / 10); e = A * B; g.setFont(new Font("Helvetica",Font.BOLD,18)); for (i=1; i<=2; i++) { g.drawString(Integer.toString(sub(A,i)),100-i*20, 20); g.drawString(Integer.toString(sub(B,i)),100-i*20, 40); } for (i=1; i<=3; i++) { g.drawString(Integer.toString(sub(c,i)),100-i*20, 60); g.drawString(Integer.toString(sub(d,i)), 80-i*20, 80); } for (i=1; i<=4; i++) g.drawString(Integer.toString(sub(e,i)),100-i*20,100); g.setFont(new Font("Helvetica",Font.PLAIN,12)); g.drawString("cnt = "+Integer.toString(cnt),30,115); } } public boolean action(Event e, Object arg) { if ("実行".equals(arg)) { if (A == 0) puzzle(); else A = cnt = 0; repaint(); } return true; } }

    • ベストアンサー
    • Java
  • JAVAのオーバーフローを取得できませんか?

    JAVAのオーバーフローを取得できませんか? while(k!=0){ k<<=1; if(キャリーフラグ的な何か){ 上記のような流れの処理を書いているのですが、こんな風に書けたらなぁ、という欲望を抱いたので質問させてもらいました。無いならないとざっくり切っていただけるとありがたい。 現状は int i=Integer.MIN_VALUE; while(k!=0){ if((k & i)!=0){ k ^= i; i >>>=1; こんな感じで見た目汚くて残念な感じです。(; ;)

    • ベストアンサー
    • Java
  • Java subSetメソッドについて

    連投になってしまい申しわけございません。 ocj-p目前でハッキリしない問題を詰めております。 subSetメソッドについて、2冊の書籍を調べたのですが 解説がどちらも違っていてハッキリしません。 例えば以下のコードについて public class A { public static void main(String[] args) { TreeSet<Integer> ts1 = new TreeSet<Integer>(); TreeSet<Integer> ts2 = new TreeSet<Integer>(); for(int i=106; i<113; i++) { if(i%2 == 0) ts1.add(i); } ts2 = (TreeSet)ts1.subSet(108, true, 111, true); ts1.add(129); System.out.println(ts1 + "" + ts2); } } 1冊目では参照型ではないという考え方でaddはts2には反映せず [106, 108, 110, 112, 129][108, 110] 2冊目では参照型であるためaddは相互には反映し [106, 108, 110, 112, 129][108, 110, 129] とあります。 どちらの考え方が正しいでしょうか? 私はずっと参照型ではない=1冊目と同じ考え方でした。 よろしくお願いいたします。

    • ベストアンサー
    • Java
  • 簡単なマインスイーパーをJavaで作りたいです。

    Javaの勉強をしたいと思い下のソースのマインスイーパーを ウィンドウ上で実行できるようにしたいです。 そのときに他のソースから呼び出す形にしたいです。 どのようにしたら良いでしょうか?教えてください。 出来ればソースがあるとありがたいです。 import java.util.Scanner; public class MineSweeper extends MinePrinter { public static void main(String[] args) { Scanner sc = new Scanner(System.in); MineSweeper game = new MineSweeper(); game.displayStrblock(); while (!game.dead) { System.out.println("\n:爆弾数・・・" + game.mines); System.out.println("\n:場所を選んでください"); System.out.println("縦の場所の数字を入力"); int tate = Integer.parseInt(sc.next()); System.out.println("横の場所の数字を入力"); int yoko = Integer.parseInt(sc.next()); game.mineClick(tate, yoko); game.displayStrblock(); } } } class MinePrinter { String[][] strblock = new String[5][5]; int[][] blocks = new int[5][5]; int mines = 0; boolean dead = false; public MinePrinter() { mineSet(); } void mineClick(int i, int j) { if (aroundManyMines(i, j) == 99) { System.out.println("burst!!!"); System.out.println("You Dead!!\n"); strblock[i][j] = "*"; dead = true; } else { strblock[i][j] = Integer.toString(aroundManyMines(i, j)); } } void mineSet() { for (int i = 0; i < blocks.length; i++) { for (int j = 0; j < blocks[i].length; j++) { if (Math.random() < 0.2) { blocks[i][j] = 99; mines += 1; } else { blocks[i][j] = 0; } } } for (int i = 0; i < strblock.length; i++) { for (int j = 0; j < strblock.length; j++) { strblock[i][j] = "#"; } } } void displayStrblock() { for (int i = 0; i < strblock.length; i++) { for (int j = 0; j < strblock.length; j++) { System.out.print(strblock[i][j] + " "); } System.out.println(":" + i); } } int aroundManyMines(int i, int j) { if (blocks[i][j] == 99) { return 99; } int ans = 0; for (int r = -1; r <= 1; r++) for (int c = -1; c <= 1; c++) { try { if (blocks[i + r][j + c] == 99) { ans += 1; } } catch (ArrayIndexOutOfBoundsException e) { continue; } } return ans; } }

    • ベストアンサー
    • Java
  • Javaを勉強しています。

    現在、Javaの勉強中なので初歩的な質問ですみません。 #色々な本やググってみたのですが、未だ理解できないでいます。 Javaでは、たとえば(1)のように左辺(List)の型と右辺(ArrayList)の型が 違う場合でも問題なく使用できるようです。 (1)と(2)で何の違いがあるのか理解できておりません。 何が違うのでしょうか。 (1)List<Integer> i = new ArrayList<Integer>(); (2)ArrayList<Integer> i = new ArrayList<Integer>(); その類件としては以下があります。。 (3)Map y = new HashMap(); (4)HashMap y = new HashMap(); ご教授いただけますと幸いです。 宜しくお願いいたします。

  • Javaアプレットとマルチスレッドの組み合わせ

    Javaアプレットとマルチスレッドを組み合わせてパラパラ漫画のようなものを作りたいのですがうまくいきません。 import java.awt.Graphics; import java.awt.Image; public class kadai4 extends java.applet.Applet implements Runnable{ Image logoImage[]; Thread runner; int current; int last=6; public void init(){ logoImage=new Image[last]; for(int i=0;i<last;i++){ logoImage[i] = getImage(getCodeBase(),"image/logo" + (i+1) + ".gif"); } } public void start(){ if(runner == null){ runner = new Thread(this); runner.start(); } } public void stop(){ if(runner != null){ runner.stop(); runner=null; } } public void run(){ while(true){ for(int i=0;i<last;i++){ current=i; repaint(); pause(400); } } } public void paint(Graphics g){ g.drawImage(logoImage[current],50,25,50,50,this); } void pause(int time){ try { Thread.sleep(time);} catch (InterruptedException e) {} } } これを実行すると推奨されない API を使用またはオーバーライドしています。というエラーが発生するのですがどうすれば良いでしょうか?他の方法でも構いません

    • ベストアンサー
    • Java
  • Java NullPointerException

    簡単な配列を作っているのですが、現在のコードについてどうしても以下のエラーが解決できません。 java.lang.NullPointerException 今作っているコードは ArrayList<Integer> intList = new intList<Integer>(); intList.add(1); といういうようなシンプルなものです。 ArrayList<Integer>ではなく、int[]にしてもダメでした。(正直この2つの違いもよく分かっていません。) 解決方法(+よろしければ違いの説明も)を教えて頂ければと思います。 宜しくお願い致します。

    • ベストアンサー
    • Java

専門家に質問してみよう