Index: build/make/targets/common_vm.xml =================================================================== --- build/make/targets/common_vm.xml (revision 517703) +++ build/make/targets/common_vm.xml (working copy) @@ -211,7 +211,7 @@ - + Index: vm/port/include/port_vmem.h =================================================================== --- vm/port/include/port_vmem.h (revision 517703) +++ vm/port/include/port_vmem.h (working copy) @@ -94,7 +94,26 @@ */ APR_DECLARE(size_t *) port_vmem_page_sizes(); +/** +* Returns the amount of currently used memory in bytes. +*/ +APR_DECLARE(size_t) port_vmem_used_size(); +/** +* Returns the amount of committed memory in bytes. +*/ +APR_DECLARE(size_t) port_vmem_committed_size(); + +/** +* Returns the amount of reserved memory in bytes. +*/ +APR_DECLARE(size_t) port_vmem_reserved_size(); + +/** +* Returns the maximum amount of memory which could be reserved in bytes. +*/ +APR_DECLARE(size_t) port_vmem_max_size(); + #ifdef __cplusplus } #endif Index: vm/port/src/vmem/linux/port_vmem.c =================================================================== --- vm/port/src/vmem/linux/port_vmem.c (revision 517703) +++ vm/port/src/vmem/linux/port_vmem.c (working copy) @@ -19,10 +19,12 @@ * @version $Revision: 1.1.2.1.4.3 $ */ +#include #include #include #include #include +#include #include "port_vmem.h" #ifdef __cplusplus @@ -131,6 +133,61 @@ return page_sizes; } +APR_DECLARE(size_t) port_vmem_used_size(){ + // TODO: Update this method when/if new common memory manager will be created + return port_vmem_committed_size(); +} + +APR_DECLARE(size_t) port_vmem_reserved_size(){ + // TODO: Update this method when/if new common memory manager will be created + return port_vmem_committed_size(); +} + +APR_DECLARE(size_t) port_vmem_committed_size(){ + char buf[PATH_MAX]; + + pid_t pid = getpid(); + sprintf(buf, "/proc/%d/statm", pid); + FILE* file = fopen(buf, "rt"); + if (!file) { + return port_vmem_page_sizes()[0]; + } + size_t vmem; + int res = sscanf(buf, "%lu", &vmem); + return vmem * port_vmem_page_sizes()[0]; +} + +APR_DECLARE(size_t) port_vmem_max_size(){ + char buf[PATH_MAX]; + + pid_t mypid = getpid(); + sprintf(buf, "/proc/%d/stat", mypid); + FILE* file = fopen(buf, "rt"); + if (!file) { + return UINT_MAX; + } + int pid, ppid, pgrp, session, tty_nr, tpgid, exit_signal, processor; + char comm[PATH_MAX]; + char state; + unsigned long flags, minflt, cminflt, majflt, cmajflt, utime, stime, + starttime, vsize, rlim, startcode, endcode, startstack, kstkesp, + kstkeip, signal, blocked, sigignore, sigcatch, wchan, nswap, cnswap; + long cutime, cstime, priority, nice, unused, itrealvalue, rss; + + int res = sscanf(buf, "%d %s %c %d %d %d %d %d %lu %lu %lu %lu " + "%lu %lu %lu %ld %ld %ld %ld %ld %ld %lu %lu %ld %lu %lu %lu " + "%lu %lu %lu %lu %lu %lu %lu %lu %lu %lu %d %d", + &pid, &comm, &state, &ppid, &pgrp, &session, &tty_nr, &tpgid, &flags, + &minflt, &cminflt, &majflt, &cmajflt, &utime, &stime, &cutime, &cstime, + &priority, &nice, &unused, &itrealvalue, &starttime, &vsize, &rss, &rlim, + &startcode, &endcode, &startstack, &kstkesp, &kstkeip, &signal, &blocked, + &sigignore, &sigcatch, &wchan, &nswap, &cnswap, &exit_signal, &processor); + if (res < 25) { // rlim position + return UINT_MAX; + }; + return rlim; +} + #ifdef __cplusplus } #endif Index: vm/port/src/vmem/win/port_vmem.c =================================================================== --- vm/port/src/vmem/win/port_vmem.c (revision 517703) +++ vm/port/src/vmem/win/port_vmem.c (working copy) @@ -20,6 +20,7 @@ */ #include +#include #include "port_vmem.h" #undef LOG_DOMAIN @@ -215,6 +216,34 @@ return page_sizes; } +APR_DECLARE(size_t) port_vmem_used_size(){ + return port_vmem_committed_size(); +} + +APR_DECLARE(size_t) port_vmem_committed_size(){ + // TODO: should return summarized commits instead of usage. + PROCESS_MEMORY_COUNTERS pmc; + if ( GetProcessMemoryInfo( GetCurrentProcess(), &pmc, sizeof(pmc)) ) { + return (pmc.QuotaNonPagedPoolUsage + pmc.QuotaPagedPoolUsage) * 1024; + } else { + return (size_t)0; + } +} + +APR_DECLARE(size_t) port_vmem_reserved_size(){ + // TODO: should return summarized reservaition instead of peak. + return port_vmem_committed_size(); +} + +APR_DECLARE(size_t) port_vmem_max_size(){ + PERFORMANCE_INFORMATION pi; + if ( GetPerformanceInfo( &pi, sizeof(pi)) ) { + return (pi.CommitLimit - pi.CommitTotal) * pi.PageSize + port_vmem_committed_size(); + } else { + return (size_t)0; + } +} + #ifdef __cplusplus } #endif Index: vm/vmcore/include/environment.h =================================================================== --- vm/vmcore/include/environment.h (revision 517703) +++ vm/vmcore/include/environment.h (working copy) @@ -248,6 +248,16 @@ apr_time_t total_compilation_time; /** + * The initial amount of Java heap memory (bytes) + */ + size_t init_gc_used_memory; + + /** + * The initial amount of used memory (bytes) + */ + size_t init_used_memory; + + /** * The VM state. See VM_STATE enum above. */ volatile int vm_state; Index: vm/vmcore/src/jni/jni.cpp =================================================================== --- vm/vmcore/src/jni/jni.cpp (revision 517703) +++ vm/vmcore/src/jni/jni.cpp (working copy) @@ -26,7 +26,9 @@ #include #include #include +#include "port_vmem.h" +#include "open/gc.h" #include "open/types.h" #include "open/hythread.h" #include "open/jthread.h" @@ -535,6 +537,12 @@ // Register created VM. APR_RING_INSERT_TAIL(&GLOBAL_VMS, java_vm, JavaVM_Internal, link); + // Store Java heap memory size after initialization + vm_env->init_gc_used_memory = (size_t)gc_total_memory(); + + // Store native memory size after initialization + vm_env->init_used_memory = port_vmem_used_size(); + status = JNI_OK; done: apr_thread_mutex_unlock(GLOBAL_LOCK); Index: vm/vmcore/src/kernel_classes/native/org_apache_harmony_lang_management_MemoryMXBeanImpl.cpp =================================================================== --- vm/vmcore/src/kernel_classes/native/org_apache_harmony_lang_management_MemoryMXBeanImpl.cpp (revision 517703) +++ vm/vmcore/src/kernel_classes/native/org_apache_harmony_lang_management_MemoryMXBeanImpl.cpp (working copy) @@ -28,8 +28,11 @@ */ #include "org_apache_harmony_lang_management_MemoryMXBeanImpl.h" +#include "open/gc.h" #include #include "environment.h" +#include "finalize.h" +#include "port_vmem.h" /* Header for class org_apache_harmony_lang_management_MemoryMXBeanImpl */ /* @@ -41,8 +44,7 @@ JNIEXPORT void JNICALL Java_org_apache_harmony_lang_management_MemoryMXBeanImpl_createMemoryManagers (JNIEnv * jenv_ext, jobject obj) { - // TODO implement this method stub correctly - TRACE2("management","createMemoryManagers stub invocation"); + TRACE2("management","MemoryMXBeanImpl_createMemoryManagers invocation"); JNIEnv_Internal *jenv = (JNIEnv_Internal *)jenv_ext; @@ -72,16 +74,18 @@ JNIEXPORT jobject JNICALL Java_org_apache_harmony_lang_management_MemoryMXBeanImpl_getHeapMemoryUsageImpl (JNIEnv * jenv_ext, jobject) { - // TODO implement this method stub correctly - TRACE2("management","getHeapMemoryUsageImpl stub invocation"); + TRACE2("management","MemoryMXBeanImpl_getHeapMemoryUsageImpl invocation"); JNIEnv_Internal *jenv = (JNIEnv_Internal *)jenv_ext; - jlong init = 1L<<21; - jlong used = 1L<<20; - jlong committed = 1L<<20; - jlong max = 1L<<22; + JavaVM * vm = NULL; + jenv_ext->GetJavaVM(&vm); + jlong init = ((JavaVM_Internal*)vm)->vm_env->init_gc_used_memory; + jlong used = gc_total_memory(); + jlong committed = gc_total_memory(); + jlong max = gc_max_memory(); + jclass memoryUsageClazz =jenv->FindClass("java/lang/management/MemoryUsage"); if (jenv->ExceptionCheck()) {return NULL;}; jmethodID memoryUsageClazzConstructor = jenv->GetMethodID(memoryUsageClazz, "", "(JJJJ)V"); @@ -101,17 +105,27 @@ JNIEXPORT jobject JNICALL Java_org_apache_harmony_lang_management_MemoryMXBeanImpl_getNonHeapMemoryUsageImpl (JNIEnv * jenv_ext, jobject) { - // TODO implement this method stub correctly - TRACE2("management","getNonHeapMemoryUsageImpl stub invocation"); + TRACE2("management","MemoryMXBeanImpl_getNonHeapMemoryUsageImpl invocation"); Global_Env* genv = VM_Global_State::loader_env; JNIEnv_Internal *jenv = (JNIEnv_Internal *)jenv_ext; - jlong init = 1L<<21; - jlong used = 1L<<20; - jlong committed = 1L<<20; - jlong max = 1L<<22; + JavaVM * vm = NULL; + jenv_ext->GetJavaVM(&vm); + jlong init = ((JavaVM_Internal*)vm)->vm_env->init_used_memory + - ((JavaVM_Internal*)vm)->vm_env->init_gc_used_memory; + if (init <= 0) {init = -1;} + + jlong used = port_vmem_used_size() - gc_total_memory(); + if (used < init) {used = init;} + + jlong committed = port_vmem_committed_size() - gc_total_memory(); + if (committed < used) {committed = used;} + + jlong max = port_vmem_max_size() - gc_total_memory(); + if (max < committed) {max = committed;} + jclass memoryUsageClazz =jenv->FindClass("java/lang/management/MemoryUsage"); if (jenv->ExceptionCheck()) {return NULL;}; jmethodID memoryUsageClazzConstructor = jenv->GetMethodID(memoryUsageClazz, "", "(JJJJ)V"); @@ -131,12 +145,14 @@ JNIEXPORT jint JNICALL Java_org_apache_harmony_lang_management_MemoryMXBeanImpl_getObjectPendingFinalizationCountImpl (JNIEnv *, jobject) { - // TODO implement this method stub correctly - TRACE2("management","getObjectPendingFinalizationCountImp stub invocation"); - return 20; + TRACE2("management","MemoryMXBeanImpl_getObjectPendingFinalizationCountImp invocation"); + return vm_get_finalizable_objects_quantity();; } -jboolean memory_bean_verbose = JNI_TRUE; +/** + * Stores current verbose state for the future request + */ +jboolean memory_bean_verbose = JNI_FALSE; /* * Class: org_apache_harmony_lang_management_MemoryMXBeanImpl @@ -146,8 +162,7 @@ JNIEXPORT jboolean JNICALL Java_org_apache_harmony_lang_management_MemoryMXBeanImpl_isVerboseImpl (JNIEnv *, jobject) { - // TODO implement this method stub correctly - TRACE2("management","MemoryMXBeanImpl_isVerboseImpl stub invocation"); + TRACE2("management","MemoryMXBeanImpl_MemoryMXBeanImpl_isVerboseImpl invocation"); return memory_bean_verbose; }; @@ -159,8 +174,8 @@ JNIEXPORT void JNICALL Java_org_apache_harmony_lang_management_MemoryMXBeanImpl_setVerboseImpl (JNIEnv *, jobject, jboolean newValue) { - // TODO implement this method stub correctly - TRACE2("management","MemoryMXBeanImpl_setVerboseImpl stub invocation"); + TRACE2("management","MemoryMXBeanImpl_MemoryMXBeanImpl_setVerboseImpl invocation"); + // TODO: switch on/off management logging according to newValue memory_bean_verbose = newValue; };
VM_STATE