195adf1ff81dec324746bef58ba8c45dc1c8f3b50Mathieu Chartier/*
295adf1ff81dec324746bef58ba8c45dc1c8f3b50Mathieu Chartier * Copyright (C) 2013 The Android Open Source Project
395adf1ff81dec324746bef58ba8c45dc1c8f3b50Mathieu Chartier *
495adf1ff81dec324746bef58ba8c45dc1c8f3b50Mathieu Chartier * Licensed under the Apache License, Version 2.0 (the "License");
595adf1ff81dec324746bef58ba8c45dc1c8f3b50Mathieu Chartier * you may not use this file except in compliance with the License.
695adf1ff81dec324746bef58ba8c45dc1c8f3b50Mathieu Chartier * You may obtain a copy of the License at
795adf1ff81dec324746bef58ba8c45dc1c8f3b50Mathieu Chartier *
895adf1ff81dec324746bef58ba8c45dc1c8f3b50Mathieu Chartier *      http://www.apache.org/licenses/LICENSE-2.0
995adf1ff81dec324746bef58ba8c45dc1c8f3b50Mathieu Chartier *
1095adf1ff81dec324746bef58ba8c45dc1c8f3b50Mathieu Chartier * Unless required by applicable law or agreed to in writing, software
1195adf1ff81dec324746bef58ba8c45dc1c8f3b50Mathieu Chartier * distributed under the License is distributed on an "AS IS" BASIS,
1295adf1ff81dec324746bef58ba8c45dc1c8f3b50Mathieu Chartier * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
1395adf1ff81dec324746bef58ba8c45dc1c8f3b50Mathieu Chartier * See the License for the specific language governing permissions and
1495adf1ff81dec324746bef58ba8c45dc1c8f3b50Mathieu Chartier * limitations under the License.
1595adf1ff81dec324746bef58ba8c45dc1c8f3b50Mathieu Chartier */
1695adf1ff81dec324746bef58ba8c45dc1c8f3b50Mathieu Chartier
1795adf1ff81dec324746bef58ba8c45dc1c8f3b50Mathieu Chartierimport java.lang.reflect.*;
1895adf1ff81dec324746bef58ba8c45dc1c8f3b50Mathieu Chartier
1995adf1ff81dec324746bef58ba8c45dc1c8f3b50Mathieu Chartierclass Main {
2095adf1ff81dec324746bef58ba8c45dc1c8f3b50Mathieu Chartier    static Object nativeLock = new Object();
2195adf1ff81dec324746bef58ba8c45dc1c8f3b50Mathieu Chartier    static int nativeBytes = 0;
2295adf1ff81dec324746bef58ba8c45dc1c8f3b50Mathieu Chartier    static Object runtime;
2395adf1ff81dec324746bef58ba8c45dc1c8f3b50Mathieu Chartier    static Method register_native_allocation;
2495adf1ff81dec324746bef58ba8c45dc1c8f3b50Mathieu Chartier    static Method register_native_free;
2595adf1ff81dec324746bef58ba8c45dc1c8f3b50Mathieu Chartier    static int maxMem = 64 * 1024 * 1024;
2695adf1ff81dec324746bef58ba8c45dc1c8f3b50Mathieu Chartier
2795adf1ff81dec324746bef58ba8c45dc1c8f3b50Mathieu Chartier    static class NativeAllocation {
2895adf1ff81dec324746bef58ba8c45dc1c8f3b50Mathieu Chartier        private int bytes;
2995adf1ff81dec324746bef58ba8c45dc1c8f3b50Mathieu Chartier
3095adf1ff81dec324746bef58ba8c45dc1c8f3b50Mathieu Chartier        NativeAllocation(int bytes) throws Exception {
3195adf1ff81dec324746bef58ba8c45dc1c8f3b50Mathieu Chartier            this.bytes = bytes;
3295adf1ff81dec324746bef58ba8c45dc1c8f3b50Mathieu Chartier            register_native_allocation.invoke(runtime, bytes);
3395adf1ff81dec324746bef58ba8c45dc1c8f3b50Mathieu Chartier            synchronized (nativeLock) {
3495adf1ff81dec324746bef58ba8c45dc1c8f3b50Mathieu Chartier                nativeBytes += bytes;
3595adf1ff81dec324746bef58ba8c45dc1c8f3b50Mathieu Chartier                if (nativeBytes > maxMem) {
3695adf1ff81dec324746bef58ba8c45dc1c8f3b50Mathieu Chartier                    throw new OutOfMemoryError();
3795adf1ff81dec324746bef58ba8c45dc1c8f3b50Mathieu Chartier                }
3895adf1ff81dec324746bef58ba8c45dc1c8f3b50Mathieu Chartier            }
3995adf1ff81dec324746bef58ba8c45dc1c8f3b50Mathieu Chartier        }
4095adf1ff81dec324746bef58ba8c45dc1c8f3b50Mathieu Chartier
4195adf1ff81dec324746bef58ba8c45dc1c8f3b50Mathieu Chartier        protected void finalize() throws Exception {
4295adf1ff81dec324746bef58ba8c45dc1c8f3b50Mathieu Chartier            synchronized (nativeLock) {
4395adf1ff81dec324746bef58ba8c45dc1c8f3b50Mathieu Chartier                nativeBytes -= bytes;
4495adf1ff81dec324746bef58ba8c45dc1c8f3b50Mathieu Chartier            }
4595adf1ff81dec324746bef58ba8c45dc1c8f3b50Mathieu Chartier            register_native_free.invoke(runtime, bytes);
4695adf1ff81dec324746bef58ba8c45dc1c8f3b50Mathieu Chartier        }
4795adf1ff81dec324746bef58ba8c45dc1c8f3b50Mathieu Chartier    }
4895adf1ff81dec324746bef58ba8c45dc1c8f3b50Mathieu Chartier
4995adf1ff81dec324746bef58ba8c45dc1c8f3b50Mathieu Chartier    public static void main(String[] args) throws Exception {
5095adf1ff81dec324746bef58ba8c45dc1c8f3b50Mathieu Chartier        Class<?> vm_runtime = Class.forName("dalvik.system.VMRuntime");
5195adf1ff81dec324746bef58ba8c45dc1c8f3b50Mathieu Chartier        Method get_runtime = vm_runtime.getDeclaredMethod("getRuntime");
5295adf1ff81dec324746bef58ba8c45dc1c8f3b50Mathieu Chartier        runtime = get_runtime.invoke(null);
5395adf1ff81dec324746bef58ba8c45dc1c8f3b50Mathieu Chartier        register_native_allocation = vm_runtime.getDeclaredMethod("registerNativeAllocation", Integer.TYPE);
5495adf1ff81dec324746bef58ba8c45dc1c8f3b50Mathieu Chartier        register_native_free = vm_runtime.getDeclaredMethod("registerNativeFree", Integer.TYPE);
5595adf1ff81dec324746bef58ba8c45dc1c8f3b50Mathieu Chartier        int count = 16;
5695adf1ff81dec324746bef58ba8c45dc1c8f3b50Mathieu Chartier        int size = 512 * 0x400;
5795adf1ff81dec324746bef58ba8c45dc1c8f3b50Mathieu Chartier        int allocation_count = 256;
5895adf1ff81dec324746bef58ba8c45dc1c8f3b50Mathieu Chartier        NativeAllocation[] allocations = new NativeAllocation[count];
5995adf1ff81dec324746bef58ba8c45dc1c8f3b50Mathieu Chartier        for (int i = 0; i < allocation_count; ++i) {
6095adf1ff81dec324746bef58ba8c45dc1c8f3b50Mathieu Chartier            allocations[i % count] = new NativeAllocation(size);
6195adf1ff81dec324746bef58ba8c45dc1c8f3b50Mathieu Chartier        }
6295adf1ff81dec324746bef58ba8c45dc1c8f3b50Mathieu Chartier        System.out.println("Test complete");
6395adf1ff81dec324746bef58ba8c45dc1c8f3b50Mathieu Chartier    }
6495adf1ff81dec324746bef58ba8c45dc1c8f3b50Mathieu Chartier}
6595adf1ff81dec324746bef58ba8c45dc1c8f3b50Mathieu Chartier
66