diff --git a/mx_proc.c b/mx_proc.c
index 67ecb2e2..48e590cc 100644
--- a/mx_proc.c
+++ b/mx_proc.c
@@ -4,10 +4,38 @@
 #include <assert.h>
 #include <dirent.h>
 #include <ctype.h>
+#include <limits.h>
 
 #include "mx_util.h"
 #include "mx_proc.h"
 
+static long long int get_rss_anon(pid_t pid) {
+    _mx_cleanup_free_ char *fname;
+    mx_asprintf_forever(&fname, "/proc/%d/status", pid);
+    _mx_cleanup_fclose_ FILE *file = fopen(fname, "r");
+    if (file == NULL)
+        return -errno;
+    _mx_cleanup_free_ char *buf = NULL;
+    size_t n = 0;
+    while(1) {
+        size_t len = getline(&buf, &n, file);
+        if (len == -1)
+            break;
+        if (strncmp(buf, "RssAnon:", 8) == 0) {
+            unsigned long long int anon_rss_kb = strtoull(buf+8, NULL, 10);
+            if (anon_rss_kb == ULLONG_MAX)
+               return -errno;
+            if (anon_rss_kb > LLONG_MAX/1024) { // anon_rss > 8 EiB
+                return -ERANGE;
+            }
+            return anon_rss_kb*1024;
+        }
+    }
+    if (feof(file))
+        return 0;  /* kernel thread */
+    return -errno;
+}
+
 static int _mx_proc_pid_stat_strscan(char *str, struct mx_proc_pid_stat *pps)
 {
     size_t res = 0;
@@ -89,30 +117,15 @@ int mx_proc_pid_stat(struct mx_proc_pid_stat **pps, pid_t pid)
 
     pstat = *pps;
     if (!pstat)
-        pstat = mx_calloc_forever(1, sizeof(*pstat));
+        *pps = pstat = mx_calloc_forever(1, sizeof(*pstat));
 
     res = mx_proc_pid_stat_read(pstat, "/proc/%d/stat", pid);
     if (res < 0)
         return res;
-
-    *pps = pstat;
-    return 0;
-}
-
-int mx_proc_pid_task_tid_stat(struct mx_proc_pid_stat **pps, pid_t pid, pid_t tid)
-{
-    struct mx_proc_pid_stat *pstat;
-    int res;
-
-    pstat = *pps;
-    if (!pstat)
-        pstat = mx_calloc_forever(1, sizeof(*pstat));
-
-    res = mx_proc_pid_stat_read(pstat, "/proc/%d/task/%d/stat", pid, tid);
-    if (res < 0)
-        return res;
-
-    *pps = pstat;
+    long long int rss_anon = get_rss_anon(pid);
+    if (rss_anon < 0)
+        return rss_anon;
+    pstat->rss_anon = rss_anon;
     return 0;
 }
 
@@ -153,7 +166,7 @@ static void mx_proc_tree_update_parent_pinfo(struct mx_proc_tree_node *this, str
     if (!this)
         return;
 
-    this->pinfo.sum_rss += pinfo->sum_rss;
+    this->pinfo.sum_rss_anon += pinfo->sum_rss_anon;
 
     mx_proc_tree_update_parent_pinfo(this->parent, pinfo);
 }
@@ -255,7 +268,7 @@ static struct mx_proc_tree_node *mx_proc_tree_add(struct mx_proc_tree *pt, struc
     pt->nentries++;
 
     new->pinfo.pstat   = pps;
-    new->pinfo.sum_rss = pps->rss;
+    new->pinfo.sum_rss_anon = pps->rss_anon;
 
     if (!(pt->root)) {
         pt->root = new;
@@ -387,9 +400,10 @@ int mx_proc_tree(struct mx_proc_tree **newtree)
 
         pps = NULL;
         res = mx_proc_pid_stat(&pps, pid);
-        if (res < 0)
+        if (res < 0) {
+            free(pps);
             continue;
-
+        }
         mx_proc_tree_add(pt, pps);
     }
     free(namelist);
diff --git a/mx_proc.h b/mx_proc.h
index d4abcb35..2a125c66 100644
--- a/mx_proc.h
+++ b/mx_proc.h
@@ -6,9 +6,7 @@
 struct mx_proc_info {
     struct mx_proc_pid_stat *pstat;
 
-    unsigned long long int sum_rss;
-
-    char **environment;
+    unsigned long long int sum_rss_anon;
 };
 
 struct mx_proc_tree {
@@ -71,12 +69,13 @@ struct mx_proc_pid_stat {
     unsigned long long int delayacct_blkio_ticks; /* 42 */
     unsigned long long int guest_time;  /* 43 */
     long long int cguest_time;          /* 44 */
+
+    unsigned long long int rss_anon;    /* from /proc/PID/status. may be null (kernel thread). unit: bytes */
 };
 
 int mx_proc_pid_stat_read(struct mx_proc_pid_stat *pps, char *fmt, ...);
 
 int mx_proc_pid_stat(struct mx_proc_pid_stat **pps, pid_t pid);
-int mx_proc_pid_task_tid_stat(struct mx_proc_pid_stat **pps, pid_t pid, pid_t tid);
 
 void mx_proc_pid_stat_free_content(struct mx_proc_pid_stat *pps);
 
diff --git a/mxqd.c b/mxqd.c
index a4c35a61..bdb31eaa 100644
--- a/mxqd.c
+++ b/mxqd.c
@@ -930,21 +930,11 @@ static int init_child_process(struct mxq_group_list *glist, struct mxq_job *job)
     rlim.rlim_cur = group->job_memory*1024*1024;
     rlim.rlim_max = group->job_memory*1024*1024;
 
-    res = setrlimit(RLIMIT_AS, &rlim);
-    if (res == -1)
-        mx_log_err("job=%s(%d):%lu:%lu setrlimit(RLIMIT_AS, ...) failed: %m",
-                    group->user_name, group->user_uid, group->group_id, job->job_id);
-
     res = setrlimit(RLIMIT_DATA, &rlim);
     if (res == -1)
         mx_log_err("job=%s(%d):%lu:%lu setrlimit(RLIMIT_DATA, ...) failed: %m",
                     group->user_name, group->user_uid, group->group_id, job->job_id);
 
-    res = setrlimit(RLIMIT_RSS, &rlim);
-    if (res == -1)
-        mx_log_err("job=%s(%d):%lu:%lu setrlimit(RLIMIT_RSS, ...) failed: %m",
-                    group->user_name, group->user_uid, group->group_id, job->job_id);
-
     /* disable core files */
     rlim.rlim_cur = 0;
     rlim.rlim_cur = 0;
@@ -1919,7 +1909,7 @@ static int killall_over_memory(struct ppidcache *ppidcache, struct mxq_server *s
                     continue;
                 }
 
-                memory = pinfo->sum_rss * pagesize / 1024;
+                memory = pinfo->sum_rss_anon / 1024;
 
                 if (jlist->max_sumrss < memory)
                     jlist->max_sumrss = memory;
diff --git a/mxqps.c b/mxqps.c
index ee21424a..65ee66ab 100644
--- a/mxqps.c
+++ b/mxqps.c
@@ -18,17 +18,13 @@ int filter(const struct dirent *d)
     return 1;
 }
 
-#define MX_PROC_TREE_NODE_IS_KERNEL_THREAD(x)  ((x)->pinfo.pstat->ppid == 0 && (x)->pinfo.sum_rss == 0)
+#define MX_PROC_TREE_NODE_IS_KERNEL_THREAD(x)  ((x)->pinfo.pstat->ppid == 0 && (x)->pinfo.sum_rss_anon == 0)
 
 int mx_proc_tree_node_print_debug(struct mx_proc_tree_node *ptn, int lvl)
 {
     assert(ptn);
 
     struct mx_proc_tree_node *current;
-    long pagesize;
-
-    pagesize = sysconf(_SC_PAGESIZE);
-    assert(pagesize);
 
     for (current = ptn; current; current=current->next) {
         if (MX_PROC_TREE_NODE_IS_KERNEL_THREAD(current))
@@ -39,8 +35,8 @@ int mx_proc_tree_node_print_debug(struct mx_proc_tree_node *ptn, int lvl)
                 current->pinfo.pstat->ppid,
                 current->pinfo.pstat->pgrp,
                 current->pinfo.pstat->session,
-                current->pinfo.pstat->rss*pagesize/1024,
-                current->pinfo.sum_rss*pagesize/1024,
+                current->pinfo.pstat->rss_anon/1024,
+                current->pinfo.sum_rss_anon/1024,
                 current->pinfo.pstat->num_threads);
 
         if (lvl>0)
diff --git a/test_parser.c b/test_parser.c
index 7ff44a04..1c56638b 100644
--- a/test_parser.c
+++ b/test_parser.c
@@ -68,7 +68,7 @@ int main() {
 
     keywordset_free(tags);
 
-    static char text[8001];
+    static char text[8002];
     text[8001] = 0;
     memset(text, '(', 8000);
     test_expression(tags, text, 1, 0);