import javafx.application.Application; import javafx.event.EventHandler; import javafx.scene.Group; import javafx.scene.Node; import javafx.scene.Scene; import javafx.scene.canvas.Canvas; import javafx.scene.canvas.GraphicsContext; import javafx.scene.image.Image; import javafx.scene.image.ImageView; import javafx.scene.image.PixelWriter; import javafx.scene.image.WritableImage; import javafx.scene.input.MouseEvent; import javafx.scene.paint.Color; import javafx.scene.paint.Paint; import javafx.stage.Stage; public class TestOOVram extends Application { static final int SCENEW = 640; static final int SCENEH = 480; static final int IMGVW = 100; static final int IMGVH = 100; static long imgmem; static long cvmem; @Override public void start(Stage stage) { final Group root = new Group(); long m = imgmem; ImageView last = null; System.out.println(String.format("attempting to allocate %,d bytes of Image objects", imgmem)); int numimages = 0; while (m >= 1024 * 1024 * 4) { root.getChildren().add(last = makeImageView(1024, 1024)); m -= 1024 * 1024 * 4; numimages++; } if (m > 0) { int w = (int) Math.sqrt(m/4); if (w == 0) { w = 1; } int h = (int) ((m/4) / w); if (h > 0) { root.getChildren().add(last = makeImageView(w, h)); m -= w * h * 4; numimages++; } } fix(last); System.out.println(String.format("%,d bytes of Image allocated in %d images", imgmem-m, numimages)); Scene scene = new Scene(root, SCENEW, SCENEH, Color.GREY); scene.addEventHandler(MouseEvent.MOUSE_CLICKED, new EventHandler() { @Override public void handle(MouseEvent event) { System.out.println(String.format("attempting to allocate %,d bytes of Canvas objects", cvmem)); long m = cvmem; Canvas last = null; int numcvs = 0; try { while (m >= 1024 * 1024 * 4) { root.getChildren().add(last = makeCanvas(1024, 1024)); m -= 1024 * 1024 * 4; numcvs++; } if (m > 0) { int w = (int) Math.sqrt(m/4); if (w == 0) { w = 1; } int h = (int) ((m/4) / w); if (h > 0) { root.getChildren().add(last = makeCanvas(w, h)); m -= w * h * 4; numcvs++; } } } catch (OutOfMemoryError e) { } fix(last); System.out.println(String.format("%,d bytes of Canvas allocated in %d canvases", cvmem-m, numcvs)); } }); stage.setScene(scene); stage.show(); } static Canvas makeCanvas(int w, int h) { Canvas cv = new Canvas(w, h); cv.setScaleX(IMGVW / (double) w); cv.setScaleY(IMGVH / (double) h); cv.setTranslateX(Math.random() * (SCENEW - IMGVW) + (IMGVW - w)/2.0); cv.setTranslateY(Math.random() * (SCENEH - IMGVH) + (IMGVH - h)/2.0); fillCheckerboard(cv, Color.BLUE, Color.GREEN); return cv; } static void fix(Canvas cv) { fillCheckerboard(cv, Color.ORANGE, Color.PURPLE); } static void fillCheckerboard(Canvas cv, Paint p1, Paint p2) { int w = (int) cv.getWidth(); int h = (int) cv.getHeight(); GraphicsContext gc = cv.getGraphicsContext2D(); int hw = w / 2; int hh = h / 2; gc.setFill(p1); gc.fillRect(0, 0, w, h); gc.setFill(p2); gc.fillRect(0, 0, hw, hh); gc.fillRect(hw, hh, w, h); } static ImageView makeImageView(int w, int h) { Image img = makeImage(w, h); ImageView imgv = new ImageView(img); imgv.setX(Math.random() * (SCENEW - IMGVW)); imgv.setY(Math.random() * (SCENEH - IMGVH)); imgv.setFitWidth(IMGVW); imgv.setFitHeight(IMGVH); return imgv; } static Image makeImage(int w, int h) { WritableImage wimg = new WritableImage(w, h); writeCheckerboard(wimg, 0xff000000, 0xffffffff); return wimg; } static void fix(ImageView last) { WritableImage wimg = (WritableImage) last.getImage(); writeCheckerboard(wimg, 0xff00ffff, 0xffff00ff); } static void writeCheckerboard(WritableImage wimg, int black, int white) { int w = (int) wimg.getWidth(); int h = (int) wimg.getHeight(); PixelWriter pw = wimg.getPixelWriter(); for (int y = 0; y < h; y++) { boolean top = y < h/2; for (int x = 0; x < w; x++) { boolean left = x < w/2; pw.setArgb(x, y, (top == left) ? black : white); } } } static long parseSize(String s) { s = s.toLowerCase(); long units = 1; if (s.endsWith("g")) { units = 1024 * 1024 * 1024; s = s.substring(0, s.length()-1); } else if (s.endsWith("m")) { units = 1024 * 1024; s = s.substring(0, s.length()-1); } else if (s.endsWith("k")) { units = 1024; s = s.substring(0, s.length()-1); } return Long.parseLong(s) * units; } public static void main(String argv[]) { if (argv.length == 1) { long mem = parseSize(argv[0]); imgmem = mem/4; cvmem = mem - imgmem/2; } else if (argv.length == 2) { imgmem = parseSize(argv[0]); cvmem = parseSize(argv[1]); } else { imgmem = parseSize("64m"); cvmem = parseSize("256m") - imgmem/2; } launch(argv); } }